Skip to content

Commit

Permalink
mps-cli-gradle-plugin: return affected models in cone of influence (#28)
Browse files Browse the repository at this point in the history
* Return affected models from cone of influence when possible

* Added tests

* Bumped version to 0.17
  • Loading branch information
kolmar authored Apr 3, 2024
1 parent 8d9fe25 commit 9b998c3
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 12 deletions.
1 change: 1 addition & 0 deletions mps-cli-gradle-plugin/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This Gradle plugin contributes the following tasks:
- `modifiedFiles` - list of paths to modified files - models, modules, root nodes, etc. (either set this input or 'referenceBranchName')
- `referenceBranchName` - the current git working tree and the commits since branching off this branch will be considered (either set this input or 'modifiedFiles')
- Outputs:
- `affectedModels` - list of models affected by modified files. If any of the modified files were moved or deleted then this is `null`.
- `affectedSolutions` - list of modules affected by the modified files. This contains the modules of the modified models and the modules dependent on them
- `affectedSolutionsAndUpstreamDependencies` - list of affected modules and all their dependencies

Expand Down
2 changes: 1 addition & 1 deletion mps-cli-gradle-plugin/plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ plugins {

// Project versions
ext.major = '0'
ext.minor = '16'
ext.minor = '17'

sourceCompatibility = 1.8
targetCompatibility = 1.8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ConeOfInfluenceComputerTest extends TestBase {
doLast {
def affectedSolutions = computeConeOfInfluence.affectedSolutions
println "all affected solutions: \${affectedSolutions.collect { it.name }.sort()}"
def affectedModels = computeConeOfInfluence.affectedModels
println "all affected models: \${affectedModels.collect { it.name }.sort()}"
}
}
"""
Expand All @@ -42,6 +44,7 @@ class ConeOfInfluenceComputerTest extends TestBase {

then:
result.output.contains twoExpectedSolutions()
result.output.contains "all affected models: []"
}

def "based on a modified root node in a model imported from other"() {
Expand All @@ -56,6 +59,7 @@ class ConeOfInfluenceComputerTest extends TestBase {
then:
result.output.contains "Computing cone of influence based on models."
result.output.contains twoExpectedSolutions()
result.output.contains "all affected models: [mps.cli.lanuse.library_second.library_top, mps.cli.lanuse.library_top.authors_top, mps.cli.lanuse.library_top.library_top]"
}

def "based on a modified root node in a model not imported from other"() {
Expand All @@ -70,6 +74,7 @@ class ConeOfInfluenceComputerTest extends TestBase {
then:
result.output.contains "Computing cone of influence based on models."
result.output.contains "all affected solutions: [mps.cli.lanuse.library_top]"
result.output.contains "all affected models: [mps.cli.lanuse.library_top.library_top]"
}

def "based on a deleted model file"() {
Expand All @@ -84,6 +89,7 @@ class ConeOfInfluenceComputerTest extends TestBase {
then:
result.output.contains "Some models moved or deleted. Computing cone of influence based on modules."
result.output.contains twoExpectedSolutions()
result.output.contains "all affected models: []"
}

def "based on a modified solution file"() {
Expand All @@ -98,5 +104,6 @@ class ConeOfInfluenceComputerTest extends TestBase {
then:
result.output.contains "Some solutions moved or deleted. Skipping cone of influence."
result.output.contains twoExpectedSolutions()
result.output.contains "all affected models: []"
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
package org.mps_cli.cone_of_influence

import groovy.transform.Immutable
import org.mps_cli.model.SModel
import org.mps_cli.model.SModuleBase
import org.mps_cli.model.SRepository

import javax.annotation.Nullable

class ConeOfInfluenceComputer {

SRepository repository

Tuple2<List<SModuleBase>, List<SModuleBase>> computeConeOfInfluence(
@Immutable
class Result {
@Nullable List<SModel> affectedModels
List<SModuleBase> affectedModules
List<SModuleBase> affectedModulesAndUpstreamDependencies

List getAt(int idx) {
switch (idx) {
case 0: return affectedModels
case 1: return affectedModules
case 2: return affectedModulesAndUpstreamDependencies
default: throw new RuntimeException("Result has 3 fields")
}
}
}

Result computeConeOfInfluence(
String rootLocation,
List<String> allModifiedFiles
) {
Expand All @@ -24,19 +44,26 @@ class ConeOfInfluenceComputer {

if (modifiedEntities.foundMissingModules) {
println("Some solutions moved or deleted. Skipping cone of influence.")
def modulesUniverse = module2AllUpstreamDependencies.keySet()
[modulesUniverse.toList(), modulesUniverse.toList()]
def modulesUniverse = module2AllUpstreamDependencies.keySet().toList()

new Result(affectedModules: modulesUniverse, affectedModulesAndUpstreamDependencies: modulesUniverse)
} else if (modifiedEntities.foundMissingModels) {
println("Some models moved or deleted. Computing cone of influence based on modules.")
computeGeneric(modifiedEntities.modules, module2AllUpstreamDependencies, module2AllDownstreamDependencies)
def (modules, modulesAndUpstreamDependencies) = (
computeGeneric(modifiedEntities.modules, module2AllUpstreamDependencies, module2AllDownstreamDependencies))

new Result(affectedModules: modules, affectedModulesAndUpstreamDependencies: modulesAndUpstreamDependencies)
} else {
println("Computing cone of influence based on models.")
def (models2AllUpstreamDependencies, models2AllDownstreamDependencies) = EntityDependenciesBuilder.buildModelDependencies(repository)

def (models, modelsAndUpstreamDependencies) =
computeGeneric(modifiedEntities.models, models2AllUpstreamDependencies, models2AllDownstreamDependencies)
def (models, modelsAndUpstreamDependencies) = (
computeGeneric(modifiedEntities.models, models2AllUpstreamDependencies, models2AllDownstreamDependencies))

[models.myModule.unique(), modelsAndUpstreamDependencies.myModule.unique()]
new Result(
affectedModels: models,
affectedModules: models.myModule.unique(),
affectedModulesAndUpstreamDependencies: modelsAndUpstreamDependencies.myModule.unique())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Filesystem2SSolutionBridge {
boolean foundMissingModels = false
Set<SModel> models = []

private boolean registerModulePath(Path path) {
private void registerModulePath(Path path) {
if (Files.notExists(path)) {
foundMissingModules = true
} else {
Expand All @@ -40,7 +40,7 @@ class Filesystem2SSolutionBridge {
}
}

private boolean registerModelPath(Path path) {
private void registerModelPath(Path path) {
if (Files.notExists(path)) {
foundMissingModels = true
} else {
Expand All @@ -55,7 +55,7 @@ class Filesystem2SSolutionBridge {
}
}

private boolean registerPath(Path path) {
private void registerPath(Path path) {
def filename = path.getFileName().toString()

if (filename.matches(modulePattern)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.mps_cli.cone_of_influence.ConeOfInfluenceComputer
import org.mps_cli.cone_of_influence.GitFacade
import org.mps_cli.model.SModel
import org.mps_cli.model.SModuleBase
import org.mps_cli.model.builder.BuildingDepthEnum
import org.mps_cli.model.builder.SModulesRepositoryBuilder
Expand All @@ -28,6 +29,9 @@ class ConeOfInfluenceComputerTask extends DefaultTask {
@Input
List<String> modifiedFiles

@Internal
List<SModel> affectedModels

@Internal
List<SModuleBase> affectedSolutions

Expand All @@ -54,7 +58,7 @@ class ConeOfInfluenceComputerTask extends DefaultTask {
def repository = builder.buildAll(sourcesDir)
def coiComputer = new ConeOfInfluenceComputer(repository: repository)

(affectedSolutions, affectedSolutionsAndUpstreamDependencies) =
(affectedModels, affectedSolutions, affectedSolutionsAndUpstreamDependencies) =
coiComputer.computeConeOfInfluence(gitRepoRootLocation, allModifiedFiles)
}
}

0 comments on commit 9b998c3

Please sign in to comment.