From 580b367486d901e932aac86cd92e14bf55495b6a Mon Sep 17 00:00:00 2001 From: Todd Morrison Date: Mon, 17 Mar 2025 06:53:15 -0500 Subject: [PATCH] fix: resolve imports in CLI by using CMLImportResolver and absolute file paths The CLI project now properly handles imports in CML files by: 1. Using CMLImportResolver to explicitly resolve imports 2. Using absolute file paths to ensure correct URI resolution 3. Updating test files to match DSL project's import syntax This aligns the CLI's import handling with the DSL project's implementation. --- .../cli/commands/GenerateCommand.java | 8 +++++++- .../cli/commands/GenerateCommandTest.java | 16 ++++++++++++++++ .../cli/commands/ValidateCommandTest.java | 13 +++++++++++++ src/test/resources/other-contexts.cml | 3 +++ src/test/resources/test-with-imports.cml | 8 ++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/other-contexts.cml create mode 100644 src/test/resources/test-with-imports.cml diff --git a/src/main/java/org/contextmapper/cli/commands/GenerateCommand.java b/src/main/java/org/contextmapper/cli/commands/GenerateCommand.java index 6a9ffe6..0e6355b 100644 --- a/src/main/java/org/contextmapper/cli/commands/GenerateCommand.java +++ b/src/main/java/org/contextmapper/cli/commands/GenerateCommand.java @@ -21,6 +21,7 @@ import org.contextmapper.dsl.standalone.ContextMapperStandaloneSetup; import org.contextmapper.dsl.standalone.StandaloneContextMapperAPI; import org.eclipse.xtext.generator.IGenerator2; +import org.contextmapper.dsl.cml.CMLImportResolver; import java.io.File; import java.util.Arrays; @@ -51,7 +52,12 @@ public void run(String[] args) { if (doesOutputDirExist(this.outputDir)) { StandaloneContextMapperAPI cmAPI = ContextMapperStandaloneSetup.getStandaloneAPI(); - CMLResource cmlResource = cmAPI.loadCML(inputPath); + File inputFile = new File(inputPath).getAbsoluteFile(); + CMLResource cmlResource = cmAPI.loadCML(inputFile); + + // Ensure imports are resolved before generation + new CMLImportResolver().resolveImportedResources(cmlResource); + cmAPI.callGenerator(cmlResource, getGenerator(cmd), this.outputDir); System.out.println("Generated into '" + this.outputDir + "'."); } diff --git a/src/test/java/org/contextmapper/cli/commands/GenerateCommandTest.java b/src/test/java/org/contextmapper/cli/commands/GenerateCommandTest.java index 09a57ff..b0a39c5 100644 --- a/src/test/java/org/contextmapper/cli/commands/GenerateCommandTest.java +++ b/src/test/java/org/contextmapper/cli/commands/GenerateCommandTest.java @@ -137,6 +137,22 @@ void run_WhenCalledWithContextMapParam_ThenGenerateContextMapFiles() { assertThat(new File("build/test-out/test_ContextMap.svg").exists()).isTrue(); } + @Test + void run_WhenCalledWithFileContainingImports_ThenGenerateFilesWithImportedContexts() throws IOException { + // given + final GenerateCommand command = spy(new GenerateCommand()); + new File("build/test-out").mkdir(); + + // when + command.run(new String[]{"-i", "src/test/resources/test-with-imports.cml", "-g", "context-map", "-o", "build/test-out"}); + + // then + assertThat(outContent.toString()).contains("Generated into 'build/test-out'."); + assertThat(new File("build/test-out/test-with-imports_ContextMap.gv").exists()).isTrue(); + assertThat(new File("build/test-out/test-with-imports_ContextMap.png").exists()).isTrue(); + assertThat(new File("build/test-out/test-with-imports_ContextMap.svg").exists()).isTrue(); + } + @Test void run_WhenCalledWithGenericParam_ThenGenerateGenericOutput() { // given diff --git a/src/test/java/org/contextmapper/cli/commands/ValidateCommandTest.java b/src/test/java/org/contextmapper/cli/commands/ValidateCommandTest.java index 217099a..25361d5 100644 --- a/src/test/java/org/contextmapper/cli/commands/ValidateCommandTest.java +++ b/src/test/java/org/contextmapper/cli/commands/ValidateCommandTest.java @@ -88,4 +88,17 @@ void run_WhenWithInvalidCMLFile_ThenPrintError() { assertThat(outContent.toString()).contains("ERROR in null on line 2:mismatched input '' expecting RULE_CLOSE"); } + @Test + void run_WhenWithFileContainingImports_ThenValidateWithoutErrors() { + // given + final ValidateCommand command = spy(new ValidateCommand()); + + // when + command.run(new String[]{"-i src/test/resources/test-with-imports.cml"}); + + // then + verify(command).printValidationMessages(any(), any()); + assertThat(outContent.toString()).contains("The CML file 'src/test/resources/test-with-imports.cml' has been validated without errors."); + } + } diff --git a/src/test/resources/other-contexts.cml b/src/test/resources/other-contexts.cml new file mode 100644 index 0000000..7e44ae6 --- /dev/null +++ b/src/test/resources/other-contexts.cml @@ -0,0 +1,3 @@ +/* Simple bounded contexts */ +BoundedContext anotherContext +BoundedContext yetAnotherContext \ No newline at end of file diff --git a/src/test/resources/test-with-imports.cml b/src/test/resources/test-with-imports.cml new file mode 100644 index 0000000..cc4d6d3 --- /dev/null +++ b/src/test/resources/test-with-imports.cml @@ -0,0 +1,8 @@ +/* Import other contexts */ +import "./other-contexts.cml" + +/* Define a simple context map */ +ContextMap SimpleMap { + contains anotherContext + contains yetAnotherContext +} \ No newline at end of file