formatools / forma Goto Github PK
View Code? Open in Web Editor NEWMeta build system with Android and Gradle support.
License: Apache License 2.0
Meta build system with Android and Gradle support.
License: Apache License 2.0
Necessary to support build types configurations for debug/release apk's.
Main steps:
Limitations:
string,
layout, // includes menu
drawable, //includes anim
style, //includes color, dimen, font
num, //includes bool, integer
other //includes xml
not final
When I open the project on Android Studio, it will show popup with:
The path
'\Users\stepango\Library\Android\sdk'
does not belong to a directory.
Android Studio will use this Android SDK instead:
'C:\Android\sdk'
and will modify the project's local.properties file.
Now api urls are located directly in NetworkModule
, in: core: network: library
Retrofit.Builder()
.baseUrl("https://gateway.marvel.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
Necessary to make configs for sample application for putting url, api versions and other transport information there. After pass these configs to component modules, like : core: network: library
Я делал небольшой пример приложения с несколькими модулями.
https://github.com/tequilaonelove/forma-sample.git
Столкнулся с какой-то странной проблемой.
При обновлении кода или макета, изменений в приложении не происходит. Например если внести какие-либо изменения в layout/activity_main.xml
, например если убрать кнопку или поменять ей текст, то при последующем запуске на реальном устройстве Run app
(Shift+F10) , - не происходит никаких изменений.
Чтобы произошли эти самые изменения, необходимо предварительно очистить весь кеш Clean Project
и заново "сбилдить" проект.
Это занимает достаточно большое время, для такого маленького изменения. Я оставил ссылку на репозиторий, где существует эта проблема, чтобы можно было её воспроизвести.
Перезагрузка Android Studio и Invalidate Caches
не помогает.. Где-то я ошибся или что-то упустил..?
Would be used for android_utils
/kt_android_utils
instead of AGP
Necessary to move features from
https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/dsl/BuildFeatures
to Forma configuration.
By default need to switch off all flags, but provide another solution for configuration BuildFeatures through Forma API
Currently Forma supports dependencies in form of String's and project
s.
However, project
function name does not correspond to internal Forma terminology as well as using Gradle API's directly which should be minimized.
Solution here is to design and implement target(...)
function to replace project
.
Options:
:parent:sub:project
\parent\sub\project
Introduce stub targets
feature-api
feature-impl
feature-stub
introduce new API for adding project dependencies
During IDE sync impl
will be substituted with stub
for improved IDE performance, using (compileOnly+runtimeOnly/implementation
) configuration based on local flags
For example, we can generate a target structure based on the initial configuration in the build file
api(
packageName = "com.stepango.blockme.character.list.api",
owner = Teams.core
)
src/main/java/com/stepango/blockme/character/list/api
folder could be generated
Need to add it to impl, androidLibrary, androidUtils, widget, androidApp
android-v*
Current client has some overhead solution for created domain models.
There're CharacterDetail
, CharacterItem
, CharacterFavorite
and all kind of this types has same structure
class [no matter] {
val id: Long,
val name: String,
val description: String,
val imageUrl: String
}
It happens, when developers doesn't use OOP concepts for created new types or not takes ready domain logic from backend.
For our sample, we need do more clearly models structure, cause it may be sensitive for semantic Forma targets, especially for dependencies.
Necessary, to hold only unique domain models and removed others.
For example, will remain:
Character
- as single a entity for our main domain logicCharacterDetail
- as a extension for ICharacter api, cause we need to show relation between models into several :api targetsCharacterItem
- need to removed. Instead use Character
as original type for list logicCharacterFavorite
- redundant type, need to remove. For saving to database, just use same DTO class, but only on data layer.Result: Need to get more clearly logic and dependencies between feature targets.
In kotlin module we can use sources with path src/main/kotlin, but in android-library module only src/main/java available out of the box. We can add kotlin directory to sourceSet for each android-library. We just need add it to androidLibraryFeatureDefinition fun.
Using symlinks - design simplified targets structure, api/impl/stub
in the same folder
Design flat directories structure to ease navigation and interactions with multiple modules
api() - java variant type, kt_api() - kotlin variant.
This type only for modules with API (abstract classes and interfaces)
Limitations
Seems has some kind problem with org.gradle.configureondemand=true
mode, when you're trying to run on emulator.
Here some log:
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':binary:compileDebugJavaWithJavac'.
> Could not resolve all dependencies for configuration ':binary:debugCompileClasspath'.
> A problem occurred configuring project ':feature:home:api'.
> org.gradle.api.internal.initialization.DefaultClassLoaderScope@275cba33 must be locked before it can be used to compute a classpath!
* Exception is:
org.gradle.api.internal.tasks.TaskDependencyResolveException: Could not determine the dependencies of task ':binary:compileDebugJavaWithJavac'.
at org.gradle.api.internal.tasks.CachingTaskDependencyResolveContext.getDependencies(CachingTaskDependencyResolveContext.java:71)
at org.gradle.execution.plan.TaskDependencyResolver.resolveDependenciesFor(TaskDependencyResolver.java:46)
at org.gradle.execution.plan.LocalTaskNode.getDependencies(LocalTaskNode.java:154)
at org.gradle.execution.plan.LocalTaskNode.resolveDependencies(LocalTaskNode.java:122)
at org.gradle.execution.plan.DefaultExecutionPlan.doAddNodes(DefaultExecutionPlan.java:171)
at org.gradle.execution.plan.DefaultExecutionPlan.addEntryTasks(DefaultExecutionPlan.java:135)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph.addEntryTasks(DefaultTaskExecutionGraph.java:160)
at org.gradle.execution.TaskNameResolvingBuildConfigurationAction.configure(TaskNameResolvingBuildConfigurationAction.java:49)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:55)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.access$000(DefaultBuildConfigurationActionExecuter.java:26)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter$1.proceed(DefaultBuildConfigurationActionExecuter.java:63)
at org.gradle.execution.DefaultTasksBuildExecutionAction.configure(DefaultTasksBuildExecutionAction.java:45)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:55)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.access$000(DefaultBuildConfigurationActionExecuter.java:26)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter$1.proceed(DefaultBuildConfigurationActionExecuter.java:63)
at org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction.configure(ExcludedTaskFilteringBuildConfigurationAction.java:48)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:55)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.lambda$select$0(DefaultBuildConfigurationActionExecuter.java:42)
at org.gradle.internal.Factories$1.create(Factories.java:31)
at org.gradle.api.internal.project.DefaultProjectStateRegistry.withMutableStateOfAllProjects(DefaultProjectStateRegistry.java:142)
at org.gradle.api.internal.project.DefaultProjectStateRegistry.withMutableStateOfAllProjects(DefaultProjectStateRegistry.java:129)
at org.gradle.execution.DefaultBuildConfigurationActionExecuter.select(DefaultBuildConfigurationActionExecuter.java:40)
at org.gradle.initialization.DefaultTaskExecutionPreparer.prepareForTaskExecution(DefaultTaskExecutionPreparer.java:38)
at org.gradle.initialization.BuildOperationFiringTaskExecutionPreparer$CalculateTaskGraph.populateTaskGraph(BuildOperationFiringTaskExecutionPreparer.java:117)
at org.gradle.initialization.BuildOperationFiringTaskExecutionPreparer$CalculateTaskGraph.run(BuildOperationFiringTaskExecutionPreparer.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
at org.gradle.initialization.BuildOperationFiringTaskExecutionPreparer.prepareForTaskExecution(BuildOperationFiringTaskExecutionPreparer.java:56)
at org.gradle.initialization.DefaultGradleLauncher.prepareTaskExecution(DefaultGradleLauncher.java:233)
at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:167)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:148)
at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:124)
at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:72)
at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:67)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:203)
at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:56)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:77)
at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.lambda$execute$0(InProcessBuildActionExecuter.java:54)
at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:53)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.lambda$execute$0(BuildTreeScopeLifecycleBuildActionExecuter.java:33)
at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:49)
at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:32)
at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:27)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:104)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:64)
at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:37)
at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.lambda$execute$0(SessionScopeLifecycleBuildActionExecuter.java:54)
at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:67)
at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:50)
at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':binary:debugCompileClasspath'.
at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.wrapException(ErrorHandlingConfigurationResolver.java:104)
at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolveBuildDependencies(ErrorHandlingConfigurationResolver.java:65)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.lambda$resolveGraphForBuildDependenciesIfRequired$6(DefaultConfiguration.java:809)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$CalculatedModelValueImpl.update(DefaultProjectStateRegistry.java:376)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveGraphForBuildDependenciesIfRequired(DefaultConfiguration.java:805)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.access$1800(DefaultConfiguration.java:148)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$SelectedArtifactsProvider.getTaskDependencyValue(DefaultConfiguration.java:1296)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$SelectedArtifactsProvider.getTaskDependencyValue(DefaultConfiguration.java:1292)
at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.visitDependencies(DefaultConfiguration.java:1335)
at org.gradle.api.internal.tasks.CachingTaskDependencyResolveContext$TaskGraphImpl.getNodeValues(CachingTaskDependencyResolveContext.java:114)
at org.gradle.internal.graph.CachingDirectedGraphWalker$GraphWithEmptyEdges.getNodeValues(CachingDirectedGraphWalker.java:213)
at org.gradle.internal.graph.CachingDirectedGraphWalker.doSearch(CachingDirectedGraphWalker.java:121)
at org.gradle.internal.graph.CachingDirectedGraphWalker.findValues(CachingDirectedGraphWalker.java:73)
at org.gradle.api.internal.tasks.CachingTaskDependencyResolveContext.getDependencies(CachingTaskDependencyResolveContext.java:69)
... 115 more
Caused by: org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':feature:home:api'.
at org.gradle.configuration.project.LifecycleProjectEvaluator.wrapException(LifecycleProjectEvaluator.java:75)
at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:68)
at org.gradle.configuration.project.LifecycleProjectEvaluator.access$400(LifecycleProjectEvaluator.java:51)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:102)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:264)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:281)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:263)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:91)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:63)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:715)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:145)
at org.gradle.api.internal.project.ConfigurationOnDemandProjectAccessListener.evaluateProjectAndDiscoverTasks(ConfigurationOnDemandProjectAccessListener.java:34)
at org.gradle.api.internal.project.ConfigurationOnDemandProjectAccessListener.beforeResolvingProjectDependency(ConfigurationOnDemandProjectAccessListener.java:30)
at org.gradle.internal.service.scopes.BuildScopeServices$1.beforeResolvingProjectDependency(BuildScopeServices.java:226)
at org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency.beforeResolved(DefaultProjectDependency.java:124)
at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.ProjectIvyDependencyDescriptorFactory.createDependencyDescriptor(ProjectIvyDependencyDescriptorFactory.java:43)
at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultDependencyDescriptorFactory.createDependencyDescriptor(DefaultDependencyDescriptorFactory.java:47)
at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependencies(DefaultLocalConfigurationMetadataBuilder.java:58)
at org.gradle.api.internal.artifacts.ivyservice.moduleconverter.dependencies.DefaultLocalConfigurationMetadataBuilder.addDependenciesAndExcludes(DefaultLocalConfigurationMetadataBuilder.java:48)
at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.realizeDependencies(DefaultLocalComponentMetadata.java:535)
at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.addDefinedExcludes(DefaultLocalComponentMetadata.java:482)
at org.gradle.internal.component.local.model.DefaultLocalComponentMetadata$DefaultLocalConfigurationMetadata.getExcludes(DefaultLocalComponentMetadata.java:473)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.computeNodeExclusions(NodeState.java:690)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.computeModuleResolutionFilter(NodeState.java:680)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.NodeState.visitOutgoingDependencies(NodeState.java:253)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.traverseGraph(DependencyGraphBuilder.java:183)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:145)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultArtifactDependencyResolver.resolve(DefaultArtifactDependencyResolver.java:145)
at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolveBuildDependencies(DefaultConfigurationResolver.java:136)
at org.gradle.api.internal.artifacts.ivyservice.ShortCircuitEmptyConfigurationResolver.resolveBuildDependencies(ShortCircuitEmptyConfigurationResolver.java:76)
at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver.resolveBuildDependencies(ErrorHandlingConfigurationResolver.java:63)
... 127 more
Caused by: java.lang.IllegalArgumentException: org.gradle.api.internal.initialization.DefaultClassLoaderScope@275cba33 must be locked before it can be used to compute a classpath!
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProvider.exportClassPathFromHierarchyOf(KotlinScriptClassPathProvider.kt:151)
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProvider.computeCompilationClassPath(KotlinScriptClassPathProvider.kt:147)
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProvider.access$computeCompilationClassPath(KotlinScriptClassPathProvider.kt:95)
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProvider$compilationClassPathOf$1.invoke(KotlinScriptClassPathProvider.kt:143)
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProvider$compilationClassPathOf$1.invoke(KotlinScriptClassPathProvider.kt:95)
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProviderKt$sam$java_util_function_Function$0.apply(KotlinScriptClassPathProvider.kt)
at org.gradle.kotlin.dsl.provider.KotlinScriptClassPathProvider.compilationClassPathOf(KotlinScriptClassPathProvider.kt:143)
at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator$InterpreterHost.compilationClassPathOf(KotlinScriptEvaluator.kt:265)
at org.gradle.kotlin.dsl.execution.Interpreter.emitSpecializedProgramFor(Interpreter.kt:260)
at org.gradle.kotlin.dsl.execution.Interpreter.eval(Interpreter.kt:183)
at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator.evaluate(KotlinScriptEvaluator.kt:124)
at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:51)
at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:36)
at org.gradle.kotlin.dsl.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:34)
at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:65)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
at org.gradle.configuration.BuildOperationScriptPlugin.lambda$apply$0(BuildOperationScriptPlugin.java:62)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:43)
at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:62)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:264)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:281)
at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:263)
at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:42)
at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:100)
... 164 more
Currently AGP and Kotlin version are taken from plugins/build.gradle.kts and values passed to configuration or explicitly specified in rootProject/build.gradle.kts are ignored. We have to fix it
Currently versionCode and versionName are placed in FormaConfiguration, but it's not global configuration responsibility to use single version configuration for whole project. We should have ability to set version code/name in binary. Maybe we have to use version code in application target, because Gradle limitations
characters:list:databinding has some domain models. It was made as a first concept, during moving all relations sources with databinding library.
And now, we're ready to move out this domain sources from characters:list:databinding
target into characters:list:api
.
Just do that ;)
(See ready solution into :characters:favorite:api
)
Need to get napt-plugin and integrate by replacing kapt behavior for java code gen.
Right now packageName
we define in build config and package in the manifest is just duplicated.
So what we need is create a universal manifest file, smth like:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="${packageName}"/>
And make sure the generation of this file is automated for every new target, or even better - use a symlink(or some other approach) to a single file for all targets which need manifest. So having AndroidManisest in every target will become obsolete
We can figure out manifest extensions for Activities later. (Like merge universal template with additional provided manifest file)
Configuration takes a lot of time with forma.
Probably it happens because of a lot of transformations like Kotlin map
or filter
in deps.
Kotlin map
creates ArrayList with 10 capacity under the hood. flatmap
creates new ArrayList
.
Sometimes we need to exclude modules from validation. For example we need it when fork some libraries to our project (like exoplayer and e.t.c)
Hi people,
I'm closely watching your progress and I like things. The only thing that stops me for trying it an overview report on the performance or build cache impact.
Do you plan something like this?
android_library - java variant, kt_android_library - kotlin variant
Limitations:
only NamedDependencies, res
and utils
dependencies allowed
the name should end with -library
Our sample uses Jetpack Navigation. It brought some strong dependencies through whole project, such as
HomeFragment.kt
...
val navController = viewBinding.bottomNavigation.setupWithNavController(
navGraphIds = navGraphIds,
fragmentManager = childFragmentManager,
containerId = R.id.nav_host_container,
intent = requireActivity().intent
)
or codegen into
CharactersListFragment.kt
...
is CharactersListViewEvent.OpenCharacterDetail ->
findNavController().navigate(
CharactersListFragmentDirections
.actionCharactersListFragmentToCharacterDetailFragment(viewEvent.id))
It's not good decision without scalable points for projects "under Forma". And we think that will be good have some abstraction navigation layer, which will protect project structure, architecture from navigation tools dependencies, especially codegen from Navigation component.
That's why need to create own navigation system, which will be use by app presentation layer. May be after, we will think about additional navigation targets for Forma.
See here, some mind ideas how it may be look
Gradle to 7.4.1 and agp to 7.1.2
Now we have support of dataBinding (contains viewBinding). We can't use Kotlin synthetic in deferent modules and it is deprecated since Kotlin 1.4.20. Need to add support of viewBinding
Legacy part of our sample doesn't have almost clean architecture.
That's why, we had some stuck trouble with relations between presentation layer and data layer.
For example check out these files CharacterPageDataSource.kt
and CharactersListViewModel.kt
and you'll see.
GlobalScope.launch(CoroutineExceptionHandler { _, _ ->
retry = {
loadInitial(params, callback)
}
networkState.postValue(NetworkState.Error())
})
DataSource shouldn't know anything about scopes.
Necessary to make sample architecture more cleaner with weak deps between presentation layer and data by implementing use case on domain layer.
It will be necessary for future, for example, to make tests functionality from Forma.
utils
- java variant, kt_utils
- kotlin variant
Limitations:
-utils
We have to add ability to enable support vector drawables library. We can do it by default for minds <= 24 or we can pass it in FormaConfiguration. Also we can combine both solutions and add it to FormaConfiguration and enable by default if misSdk <= 24
I've been trying to make a module for three hours already.
Caused by: com.stepango.forma.error.ProjectValidationError: Project example: name does not match type requirements
Projects of type "LibraryTarget" should contain name suffix "library"
at com.stepango.forma.validation.ValidatorKt.throwProjectValidationError(Validator.kt:44)
at com.stepango.forma.validation.ValidatorKt.validateName(Validator.kt:36)
at com.stepango.forma.validation.ValidatorKt$validator$1.validate(Validator.kt:26)
at com.stepango.forma.validation.ValidatorKt.validate(Validator.kt:21)
at AndroidUtilKt.androidUtil(androidUtil.kt:42)
at AndroidUtilKt.androidUtil$default(androidUtil.kt:72)
at Build_gradle.<init>(Unknown Source)
... 136 more
file build.gradle.kts in my example-module:
plugins {
id("com.android.library")
id("kotlin-android")
}
repositories {
jcenter()
google()
}
androidLibrary(
packageName = "com.example",
dependencies = deps(
androidxDeps.core,
androidxDeps.appcompat,
androidxDeps.material,
androidxDeps.constraintlayout
)
)
what am I doing wrong? Thanks. :)
Rewrite details feature using view binding and keep only api and impl modules to show example of using #98
deps-v*
Validation rules:
Self-validation(name)
Dependencies validation(test, annotationPrecessor, projects)
Content validation
With manifest generation feature enabled autocomplete and auto import for packege.R and package.viewbinding.databinding doest work. Android Studio detect it as error, but it still compiled correctly. Also it start work if you create manifest file in main source set with same package like in build.gradle.kts file and keep manifest generation turned on.
Currently we have similar problem in view binding target: we need to manually import our viewbinding, but unless to Manifest generation, autocomplete works correctly for binding fields (it doest work for R in manifest generation)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.