Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add build.jbang support #28

Merged
merged 1 commit into from
Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
dev.jbang.eclipse.site/target/flat-repository/*
- name: Upload code coverage
uses: codecov/codecov-action@v3
if: github.ref == 'refs/heads/main' && runner.os == 'Linux'
if: runner.os == 'Linux'
with:
files: ./coverage/target/site/jacoco-aggregate/jacoco.xml
flags: ${{ runner.os }} # optional
Expand Down
2 changes: 1 addition & 1 deletion dev.jbang.eclipse.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</runtime>
<builder id="dev.jbang.eclipse.core.jbangbuilder"/>
</extension>
<extension point="org.eclipse.core.resources.markers"
<extension point="org.eclipse.core.resources.markers"
id="dev.jbang.eclipse.core.jbangproblem"
name="JBang Problem">
<super type="org.eclipse.core.resources.problemmarker"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static File getContainerStateFile(IProject project) {


public static boolean isOnClasspath(IJavaProject javaProject, IFile script) throws CoreException {
if (script != null && JavaCore.isJavaLikeFileName(script.getName())) {
if (script != null && (JavaCore.isJavaLikeFileName(script.getName()) || JBangFileUtils.isJBangBuildFile(script)) ) {
IClasspathEntry[] entries = javaProject.getRawClasspath();
for (IClasspathEntry entry : entries) {
if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE &&
Expand All @@ -110,6 +110,24 @@ public static boolean isOnClasspath(IJavaProject javaProject, IFile script) thro
return false;
}

public static boolean isOnOutputLocation(IJavaProject javaProject, IFile script) throws CoreException {
if (script != null) {
if (javaProject.getOutputLocation() != null && javaProject.getOutputLocation().isPrefixOf(script.getFullPath())) {
return true;
}

IClasspathEntry[] entries = javaProject.getRawClasspath();
for (IClasspathEntry entry : entries) {
if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE &&
entry.getOutputLocation() != null &&
entry.getOutputLocation().isPrefixOf(script.getFullPath())) {
return true;
}
}
}
return false;
}


public static boolean hasAttribute(IClasspathEntry entry, String attribute) throws CoreException {
for (IClasspathAttribute attr : entry.getExtraAttributes()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,31 @@ public final class JBangConstants {
public static final String BUILDER_ID = PLUGIN_ID + ".jbangbuilder"; //$NON-NLS-1$

public static final String MARKER_ID = PLUGIN_ID + ".jbangproblem"; //$NON-NLS-1$

public static final String MARKER_RESOLUTION_ID = MARKER_ID + ".resolution"; //$NON-NLS-1$

private static final String PREFIX = "dev.jbang.";

/** String, list of configured JBang installations separated by '|', see {@link JBangRuntimeManager} */
public static final String P_RUNTIMES = PREFIX + "runtimes"; //$NON-NLS-1$

/** Root node of extended JBang installation attributes, see {@link JBangRuntimeManager} */
public static final String P_RUNTIMES_NODE = PREFIX + "runtimesNodes"; //$NON-NLS-1$
private static final String PREFIX = "dev.jbang.";

/** String */
public static final String P_DEFAULT_RUNTIME = PREFIX + "defaultRuntime"; //$NON-NLS-1$
/**
* String, list of configured JBang installations separated by '|', see
* {@link JBangRuntimeManager}
*/
public static final String P_RUNTIMES = PREFIX + "runtimes"; //$NON-NLS-1$

/**
* Root node of extended JBang installation attributes, see
* {@link JBangRuntimeManager}
*/
public static final String P_RUNTIMES_NODE = PREFIX + "runtimesNodes"; //$NON-NLS-1$

public static final String P_DEFAULT_RUNTIME = PREFIX + "defaultRuntime"; //$NON-NLS-1$

public static final String JBANG_BUILD = "build.jbang";

private JBangConstants(){
//no instanciation
}
public static final String JBANG_MAIN = "main.java";

private JBangConstants() {
// no instanciation
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package dev.jbang.eclipse.core.internal;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.file.Files;
Expand All @@ -15,7 +12,6 @@

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
Expand Down Expand Up @@ -67,6 +63,13 @@ public static boolean isJBangFile(IResource resource) {
return false;
}

public static boolean isJBangBuildFile(IResource resource) {
if (!(resource instanceof IFile)) {
return false;
}
return JBangConstants.JBANG_BUILD.equals(((IFile) resource).getName());
}

public static boolean isJBangFile(Path file) {
if (!(Files.isRegularFile(file))) {
return false;
Expand All @@ -84,6 +87,20 @@ public static boolean isJBangFile(Path file) {
return false;
}

public static boolean isJBangBuildFile(Path file) {
if (!(Files.isRegularFile(file))) {
return false;
}
return JBangConstants.JBANG_BUILD.equals(file.getFileName().toString());
}

public static boolean isMainFile(Path file) {
if (!(Files.isRegularFile(file))) {
return false;
}
return JBangConstants.JBANG_MAIN.equals(file.getFileName().toString());
}

public static String getJavaVersion(String line) {
return getMatch(JAVA_INSTRUCTION, line);
}
Expand Down Expand Up @@ -114,28 +131,33 @@ private static String getMatch(Pattern pattern, String line) {

public static String getPackageName(IJavaProject javaProject, IFile file) {
//TODO probably not the most efficient way to get the package name as this reads the whole file;
char[] source = null;
try (InputStream is = new BufferedInputStream(file.getContents(true));
ByteArrayOutputStream result = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
for (int length; (length = is.read(buffer)) != -1; ) {
result.write(buffer, 0, length);
}
source = result.toString(file.getCharset()).toCharArray();
} catch (IOException | CoreException e) {
var ast = createCompilationUnit(file);
if (ast != null) {
PackageDeclaration pkg = ast.getPackage();
if (pkg != null && pkg.getName() != null) {
return pkg.getName().getFullyQualifiedName();
}
}
return null;
}

public static CompilationUnit createCompilationUnit(IFile file) {
String content = null;
try {
content = ResourceUtil.getContent(file);
} catch (Exception e) {
e.printStackTrace();
}
if (source == null) {
if (content == null) {
return null;
}
char[] source = content.toCharArray();

ASTParser parser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
parser.setProject(javaProject);
parser.setIgnoreMethodBodies(true);
parser.setSource(source);
CompilationUnit ast = (CompilationUnit) parser.createAST(null);
PackageDeclaration pkg = ast.getPackage();
return (pkg == null || pkg.getName() == null)? null :pkg.getName().getFullyQualifiedName();
return ast;
}

private static boolean hasJBangInstructions(Reader reader) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dev.jbang.eclipse.core.internal.builder;

import static dev.jbang.eclipse.core.JBangCorePlugin.logInfo;
import static dev.jbang.eclipse.core.internal.JBangFileUtils.createCompilationUnit;
import static dev.jbang.eclipse.core.internal.JBangFileUtils.isJBangBuildFile;
import static dev.jbang.eclipse.core.internal.JBangFileUtils.isJBangFile;

import java.util.ArrayList;
Expand All @@ -26,6 +28,7 @@
import org.eclipse.jdt.core.manipulation.CoreASTProvider;

import dev.jbang.eclipse.core.JBangCorePlugin;
import dev.jbang.eclipse.core.internal.ResourceUtil;
import dev.jbang.eclipse.core.internal.project.JBangProject;
import dev.jbang.eclipse.core.internal.project.ProjectConfigurationManager;
import dev.jbang.eclipse.core.internal.runtime.JBangRuntimesDiscoveryJob;
Expand Down Expand Up @@ -143,7 +146,7 @@ public boolean visit(IResourceDelta delta) {
case IResourceDelta.CHANGED: {
// if the content has changed clean + scan
if ((delta.getFlags() & IResourceDelta.CONTENT) > 0) {
if (isJBangFile(resource)) {
if (isJBangBuildFile(resource) || isJBangFile(resource)) {
jbangFiles.add((IFile) resource);
}
return true;
Expand All @@ -166,21 +169,34 @@ void cleanMarkers(IProject p) {

@SuppressWarnings("unchecked")
static Integer getConfigHash(IFile file, IProgressMonitor monitor) throws CoreException {
if (!"java".equals(file.getFileExtension())) {
if (!JavaCore.isJavaLikeFileName(file.getName()) && !isJBangBuildFile(file) ) {
return null;
}
ICompilationUnit typeRoot = JavaCore.createCompilationUnitFrom(file);
//FIXME This is uber slow. Once a file is saved, its AST is disposed, we're not benefiting from reusing a cached AST,
// hence pay the price of recomputing it from scratch
CompilationUnit root = CoreASTProvider.getInstance().getAST(typeRoot, CoreASTProvider.WAIT_YES, monitor);

CompilationUnit root = null;
String source = null;
if (isJBangBuildFile(file)) {
root = createCompilationUnit(file);
source = ResourceUtil.getContent(file);
} else {
ICompilationUnit typeRoot = JavaCore.createCompilationUnitFrom(file);
if (typeRoot != null) {
//FIXME This is uber slow. Once a file is saved, its AST is disposed, we're not benefiting from reusing a cached AST,
// hence pay the price of recomputing it from scratch
root = CoreASTProvider.getInstance().getAST(typeRoot, CoreASTProvider.WAIT_YES, monitor);
source = typeRoot.getSource();
}
}
if (root == null) {
return 0;
}
JBangConfigVisitor configCollector = new JBangConfigVisitor(typeRoot.getSource());

JBangConfigVisitor configCollector = new JBangConfigVisitor(source);
root.accept(configCollector);
for (Comment comment : (List<Comment>) root.getCommentList()) {
comment.accept(configCollector);
}
return configCollector.getConfigElements().hashCode();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -21,14 +20,10 @@
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;

import dev.jbang.eclipse.core.internal.classpath.AnnotationServiceLocator.ServiceEntry;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class JBangResourceTester extends PropertyTester {
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
if (receiver instanceof IResource) {
IResource resource = (IResource) receiver;
boolean isJBangFile = JBangFileUtils.isJBangFile(resource);
boolean isJBangFile = JBangFileUtils.isJBangFile(resource) || JBangFileUtils.isJBangBuildFile(resource);
return Objects.equals(isJBangFile, expectedValue);
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) {
var configuration = new JBangProjectConfiguration();
for (Path script : scripts) {
try {
if (JBangFileUtils.isJBangFile(script)) {
if (JBangFileUtils.isJBangFile(script) || JBangFileUtils.isJBangBuildFile(script)) {
projectManager.createJBangProject(script, configuration, monitor);
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;

import dev.jbang.eclipse.core.JBangCorePlugin;
import dev.jbang.eclipse.core.internal.JBangClasspathUtils;
import dev.jbang.eclipse.core.internal.JBangConstants;
import dev.jbang.eclipse.core.internal.JBangFileUtils;
import dev.jbang.eclipse.core.internal.ProjectUtils;
import dev.jbang.eclipse.core.internal.ResourceUtil;
import dev.jbang.eclipse.core.internal.classpath.AnnotationProcessorUtils;
Expand Down Expand Up @@ -315,6 +315,9 @@ public JBangProject createJBangProject(java.nio.file.Path script, JBangProjectCo

String fileName = script.getFileName().toString();
String name = fileName; //fileName.substring(0, fileName.lastIndexOf("."));
if (JBangFileUtils.isJBangBuildFile(script) || JBangFileUtils.isMainFile(script)) {
name = script.getParent().getFileName().toString();
}

IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (!project.exists()) {
Expand Down Expand Up @@ -353,7 +356,12 @@ public JBangProject createJBangProject(java.nio.file.Path script, JBangProjectCo

javaProject.setOutputLocation(bin.getFullPath(), monitor);

IFile mainFile = link(info.getBackingResource(), project, configuration, monitor);
IFile mainFile;
if (JBangFileUtils.isJBangBuildFile(script)) {
mainFile = link(script.toAbsolutePath().toString(), project, configuration, monitor);
} else {
mainFile = link(info.getBackingResource(), project, configuration, monitor);
}
if (info.getSources() != null && !info.getSources().isEmpty()) {
for (JBangFile s : info.getSources()) {
link(s.originalResource, project, configuration, monitor);
Expand Down Expand Up @@ -398,12 +406,18 @@ private IFile link(String resource, String link, IProject project, JBangProjectC
}

public void synchronize(IFile file, IProgressMonitor monitor) throws CoreException {
monitor.setTaskName("Updating JBang configuration from " + file.getName());
//System.err.println(file + " configuration changed, checking jbang info");
JBangProject jbp = getJBangProject(file.getProject(), monitor);
IProject project = file.getProject();
JBangProject jbp = getJBangProject(project, monitor);
if (jbp == null) {
return;
}

if (isJavaProject(project) && JBangClasspathUtils.isOnOutputLocation(JavaCore.create(project), file)) {
return;
}
monitor.setTaskName("Updating JBang configuration from " + file.getName());

jbp.setMainSourceFile(file);
var jbang = jbp.getRuntime();

Expand All @@ -424,10 +438,12 @@ public void synchronize(IFile file, IProgressMonitor monitor) throws CoreExcepti
});
}
}

}

private String getSource(IFile file) throws JavaModelException {
private String getSource(IFile file) throws CoreException {
if (JBangFileUtils.isJBangBuildFile(file)) {
return ResourceUtil.getContent(file);
}
ICompilationUnit typeRoot = JavaCore.createCompilationUnitFrom(file);
return typeRoot.getBuffer().getContents();
}
Expand Down
Loading