Skip to content

Commit

Permalink
Merge pull request #43578 from NipunaRanasinghe/debugger-persist-sour…
Browse files Browse the repository at this point in the history
…ces-fix-u11

[Debugger] Update debugger project loader to support bal persist sources
  • Loading branch information
NipunaRanasinghe authored Nov 14, 2024
2 parents c64ca77 + 574e734 commit d25f02f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,18 @@
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.StringJoiner;

import static io.ballerina.projects.util.ProjectConstants.BALLERINA_TOML;
import static io.ballerina.projects.util.ProjectPaths.isBalFile;
import static org.ballerinalang.debugadapter.DebugSourceType.DEPENDENCY;
import static org.ballerinalang.debugadapter.DebugSourceType.PACKAGE;
import static org.ballerinalang.debugadapter.evaluation.IdentifierModifier.encodeModuleName;
Expand All @@ -60,6 +62,7 @@ public final class PackageUtils {
public static final String GENERATED_VAR_PREFIX = "$";
static final String USER_MODULE_DIR = "modules";
static final String GEN_MODULE_DIR = "generated";
static final String PERSIST_DIR = "persist";
static final String TEST_PKG_POSTFIX = "$test";
private static final String URI_SCHEME_FILE = "file";
private static final String URI_SCHEME_BALA = "bala";
Expand Down Expand Up @@ -111,15 +114,57 @@ public static Optional<Map.Entry<Path, DebugSourceType>> getStackFrameSourcePath
* @return A pair of project kind and the project root.
*/
public static Map.Entry<ProjectKind, Path> computeProjectKindAndRoot(Path path) {
if (ProjectPaths.isStandaloneBalFile(path)) {
if (ProjectPaths.isStandaloneBalFile(path) && !isBalToolSpecificFile(path)) {
return new AbstractMap.SimpleEntry<>(ProjectKind.SINGLE_FILE_PROJECT, path);
}
// Following is a temp fix to distinguish Bala and Build projects.
Path tomlPath = ProjectPaths.packageRoot(path).resolve(ProjectConstants.BALLERINA_TOML);
if (Files.exists(tomlPath)) {
return new AbstractMap.SimpleEntry<>(ProjectKind.BUILD_PROJECT, ProjectPaths.packageRoot(path));
// TODO: Revert 'findProjectRoot()' to `ProjectPaths.packageRoot()` API once
// https://github.com/ballerina-platform/ballerina-lang/issues/43538#issuecomment-2469488458
// is addressed from the Ballerina platform side.
Optional<Path> packageRoot = findProjectRoot(path);
if (packageRoot.isEmpty()) {
return new AbstractMap.SimpleEntry<>(ProjectKind.SINGLE_FILE_PROJECT, path);
} else if (hasBallerinaToml(packageRoot.get())) {
return new AbstractMap.SimpleEntry<>(ProjectKind.BUILD_PROJECT, packageRoot.get());
} else {
return new AbstractMap.SimpleEntry<>(ProjectKind.BALA_PROJECT, packageRoot.get());
}
return new AbstractMap.SimpleEntry<>(ProjectKind.BALA_PROJECT, ProjectPaths.packageRoot(path));
}

private static boolean isBalToolSpecificFile(Path filePath) {
// TODO: Remove after https://github.com/ballerina-platform/ballerina-lang/issues/43538#issuecomment-2469488458
// is addressed from the Ballerina platform side.
Path parentPath = filePath.toAbsolutePath().normalize().getParent();
return isBalFile(filePath)
&& parentPath.toFile().isDirectory()
&& parentPath.toFile().getName().equals(PERSIST_DIR)
&& hasBallerinaToml(parentPath.getParent());
}

private static boolean hasBallerinaToml(Path filePath) {
if (Objects.isNull(filePath)) {
return false;
}
Path absFilePath = filePath.toAbsolutePath().normalize();
return absFilePath.resolve(BALLERINA_TOML).toFile().exists();
}

private static Optional<Path> findProjectRoot(Path filePath) {
if (filePath == null) {
return Optional.empty();
}

filePath = filePath.toAbsolutePath().normalize();
if (filePath.toFile().isDirectory()) {
if (hasBallerinaToml(filePath) || hasPackageJson(filePath)) {
return Optional.of(filePath);
}
}
return findProjectRoot(filePath.getParent());
}

private static boolean hasPackageJson(Path filePath) {
Path absFilePath = filePath.toAbsolutePath().normalize();
return absFilePath.resolve(ProjectConstants.PACKAGE_JSON).toFile().exists();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,40 @@
public class DebugEngageTest extends BaseTestCase {

DebugTestRunner debugTestRunner;
private static final String TEST_PROJECT_NAME = "basic-project";

@Override
@BeforeClass
public void setup() {
String testProjectName = "breakpoint-tests";
String testModuleFileName = "Ballerina.toml";
debugTestRunner = new DebugTestRunner(testProjectName, testModuleFileName, true);
}

@Test(description = "Debug engage test for launch mode, with special ballerina project files as input(i.e. " +
"Ballerina.toml, Dependencies.toml, etc.)")
public void testNonBallerinaInputSource() throws BallerinaTestException {
Path breakpointFilePath = debugTestRunner.testProjectPath.resolve("main.bal");
debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(breakpointFilePath, 22));
@Test(description = "Debug engage test (launch mode), with special ballerina project files as inputs" +
"(i.e. Ballerina.toml, Dependencies.toml, etc.)")
public void testDebugLaunchWithNonBallerinaFiles() throws BallerinaTestException {
String balTomlFile = "Ballerina.toml";
debugTestRunner = new DebugTestRunner(TEST_PROJECT_NAME, balTomlFile, true);
Path breakpointFilePath = debugTestRunner.testProjectPath.resolve("hello_world.bal");
debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(breakpointFilePath, 19));
debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.RUN);

// Test for debug engage
Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(25000);
Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(0));
}

@Test(description = "Debug engage test (launch mode), with special Ballerina project files as inputs " +
"(i.e. persist/model.bal, etc.)")
public void testDebugLaunchWithBallerinaToolFiles() throws BallerinaTestException {
String balPersistModelFile = "persist/model.bal";
debugTestRunner = new DebugTestRunner(TEST_PROJECT_NAME, balPersistModelFile, true);
Path breakpointFilePath = debugTestRunner.testProjectPath.resolve("hello_world.bal");
debugTestRunner.addBreakPoint(new BallerinaTestDebugPoint(breakpointFilePath, 19));
debugTestRunner.initDebugSession(DebugUtils.DebuggeeExecutionKind.RUN);
// Test for debug engage
Pair<BallerinaTestDebugPoint, StoppedEventArguments> debugHitInfo = debugTestRunner.waitForDebugHit(25000);
Assert.assertEquals(debugHitInfo.getLeft(), debugTestRunner.testBreakpoints.get(0));
}

@Override
@AfterMethod(alwaysRun = true)
public void cleanUp() {
Expand Down

0 comments on commit d25f02f

Please sign in to comment.