diff --git a/gradle.properties b/gradle.properties index ed77fa4c11..4006c4b3ed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,6 +20,7 @@ shadowJarVersion=7.1.2 spotlessVersion=6.11.0 xtextGradleVersion=3.0.0 xtextVersion=2.28.0 +klighdVersion=2.2.1-SNAPSHOT [manifestPropertyNames] org.eclipse.xtext=xtextVersion diff --git a/org.lflang.diagram/META-INF/MANIFEST.MF b/org.lflang.diagram/META-INF/MANIFEST.MF index ac3c71aa3e..b11524c688 100644 --- a/org.lflang.diagram/META-INF/MANIFEST.MF +++ b/org.lflang.diagram/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Bundle-ActivationPolicy: lazy Require-Bundle: de.cau.cs.kieler.klighd;bundle-version="2.2.0", de.cau.cs.kieler.klighd.krendering.extensions;bundle-version="2.2.0", de.cau.cs.kieler.klighd.lsp;bundle-version="2.2.0", + de.cau.cs.kieler.kgraph.text;bundle-version="2.2.0", com.google.guava, org.eclipse.xtext, org.eclipse.xtext.xbase.lib, diff --git a/org.lflang.diagram/build.gradle b/org.lflang.diagram/build.gradle new file mode 100644 index 0000000000..bd14ca4a2c --- /dev/null +++ b/org.lflang.diagram/build.gradle @@ -0,0 +1,108 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +repositories { + mavenCentral() + // TODO Remove this in-official maven repository as soon as Klighd is released to maven central in the future. + maven { + url "https://rtsys.informatik.uni-kiel.de/~kieler/files/repo/" + } +} +dependencies { + implementation project(':org.lflang') + implementation project(':org.lflang.ide') + implementation "org.eclipse.xtext:org.eclipse.xtext.ide:${xtextVersion}" + implementation ("de.cau.cs.kieler.klighd:de.cau.cs.kieler.klighd.lsp:${klighdVersion}") { + exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt.*' + exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt' + } + implementation ("de.cau.cs.kieler.klighd:de.cau.cs.kieler.klighd.standalone:${klighdVersion}") { + exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt.*' + exclude group: 'org.eclipse.platform', module: 'org.eclipse.swt' + } +} + +apply plugin: 'application' +apply plugin: 'com.github.johnrengelman.shadow' + +task generateLanguageDiagramServer { + description 'Creates a jar that implements a language server with diagram support for LF.' + + apply plugin: 'java' + apply plugin: 'application' + apply plugin: 'com.github.johnrengelman.shadow' + + mainClassName = "org.lflang.diagram.lsp.LanguageDiagramServer" + + compileJava { + options.compilerArgs << '-Xlint:unchecked' + } + + shadowJar { + classifier = 'lds' + + // Handling of service loader registrations via META-INF/services/* + mergeServiceFiles() + + // Merge properties + transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer){ + resource = 'plugin.properties' + } + + // Exclude files that are known to be dispensable for a language server + exclude( + '*._trace', + '*.ecore', + '*.ecorediag', + '*.g', + '*.genmodel', + '*.html', + '*.mwe2', + '*.profile', + '*.xtext', + '*readme.txt', + '.api_description', + '.options', + 'about.*', + 'about_*', + 'about_files/*', + 'ant_tasks/*', + 'cheatsheets/*', + 'com/*/*.java', + 'de/*/*.java', + 'docs/*', + 'log4j.properties', + 'META-INF/*.DSA', + 'META-INF/*.RSA', + 'META-INF/*.SF', + 'META-INF/changelog.txt', + 'META-INF/DEPENDENCIES', + 'META-INF/eclipse.inf', + 'META-INF/INDEX.LIST', + 'META-INF/maven/*', + 'META-INF/NOTICE', + 'META-INF/NOTICE.txt', + 'META-INF/p2.inf', + 'META-INF/versions/*/module-info.class', + 'modeling32.png', + 'module-info.class', + 'org/*/*.java', + 'OSGI-INF/l10n/bundle.properties', + 'plugin.xml', + 'profile.list', + 'schema/*', + 'systembundle.properties', + 'xtend-gen/*', + 'xtext32.png', + ) + + // Minimizing should be enabled with caution because some classes are only + // loaded via services (e.g. diagram syntheses and some xtext aspects) + // and would be removed when minimized + // minimize() { + // exclude(dependency('log4j:log4j:.*')) + // exclude(dependency('org.eclipse.xtext:.*ide:.*')) + // } + } +} + +generateLanguageDiagramServer.finalizedBy shadowJar diff --git a/org.lflang.diagram/META-INF/services/de.cau.cs.kieler.klighd.IKlighdStartupHook b/org.lflang.diagram/src/META-INF/services/de.cau.cs.kieler.klighd.IKlighdStartupHook similarity index 100% rename from org.lflang.diagram/META-INF/services/de.cau.cs.kieler.klighd.IKlighdStartupHook rename to org.lflang.diagram/src/META-INF/services/de.cau.cs.kieler.klighd.IKlighdStartupHook diff --git a/org.lflang.diagram/src/org/lflang/diagram/lsp/LanguageDiagramServer.java b/org.lflang.diagram/src/org/lflang/diagram/lsp/LanguageDiagramServer.java index 439f290b7c..cdb3da5db0 100644 --- a/org.lflang.diagram/src/org/lflang/diagram/lsp/LanguageDiagramServer.java +++ b/org.lflang.diagram/src/org/lflang/diagram/lsp/LanguageDiagramServer.java @@ -2,11 +2,20 @@ import java.util.List; -import org.eclipse.xtext.ide.server.LanguageServerImpl; +import org.eclipse.xtext.Constants; +import org.eclipse.xtext.IGrammarAccess; import org.eclipse.xtext.ide.server.ILanguageServerExtension; +import org.eclipse.xtext.ide.server.LanguageServerImpl; import org.eclipse.xtext.service.AbstractGenericModule; +import org.eclipse.xtext.util.Modules2; +import org.lflang.generator.LanguageServerErrorReporter; +import org.lflang.ide.LFIdeSetup; + import com.google.inject.Module; +import com.google.inject.name.Names; import com.google.inject.util.Modules; + +import de.cau.cs.kieler.kgraph.text.services.KGraphGrammarAccess; import de.cau.cs.kieler.klighd.lsp.KGraphLanguageClient; import de.cau.cs.kieler.klighd.lsp.interactive.layered.LayeredInteractiveLanguageServerExtension; import de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.RectpackingInteractiveLanguageServerExtension; @@ -16,9 +25,6 @@ import de.cau.cs.kieler.klighd.lsp.launch.ILanguageRegistration; import de.cau.cs.kieler.klighd.lsp.launch.Language; -import org.lflang.ide.LFIdeSetup; -import org.lflang.generator.LanguageServerErrorReporter; - /** * Language server with extended diagram communication. * @@ -30,10 +36,14 @@ private static class LFLsCreator extends AbstractLsCreator { @Override public Module createLSModules(boolean socket) { - return Modules.override(super.createLSModules(socket)).with(new AbstractGenericModule() { + return Modules2.mixin(Modules.override(super.createLSModules(socket)).with(new AbstractGenericModule() { public Class bindLanguageServerImpl() { return LFLanguageServer.class; } + }), it -> { + // Temporary fix for an issue of Klighd with Xtext 2.28 (https://github.com/kieler/KLighD/issues/144) + it.bind(IGrammarAccess.class).to(KGraphGrammarAccess.class); + it.bind(String.class).annotatedWith(Names.named(Constants.LANGUAGE_NAME)).toInstance("de.cau.cs.kieler.kgraph.text.KGraph"); }); } diff --git a/org.lflang.diagram/src/org/lflang/diagram/synthesis/util/ReactorIcons.java b/org.lflang.diagram/src/org/lflang/diagram/synthesis/util/ReactorIcons.java index 71f30e491b..fea03f819d 100644 --- a/org.lflang.diagram/src/org/lflang/diagram/synthesis/util/ReactorIcons.java +++ b/org.lflang.diagram/src/org/lflang/diagram/synthesis/util/ReactorIcons.java @@ -27,8 +27,8 @@ import java.io.InputStream; import java.util.HashMap; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; +//import org.eclipse.swt.graphics.ImageData; +//import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.xtext.xbase.lib.Extension; import org.lflang.ASTUtils; import org.lflang.AttributeUtils; @@ -57,10 +57,10 @@ public class ReactorIcons extends AbstractSynthesisExtensions { @Inject @Extension private KRenderingExtensions _kRenderingExtensions; @Inject @Extension private KContainerRenderingExtensions _kContainerRenderingExtensions; - private static final ImageLoader LOADER = new ImageLoader(); +// private static final ImageLoader LOADER = new ImageLoader(); // Image cache during synthesis - private final HashMap cache = new HashMap<>(); +// private final HashMap cache = new HashMap<>(); // Error message private String error = null; @@ -83,68 +83,74 @@ public void handleIcon(KContainerRendering rendering, ReactorDecl reactor, boole if (iconLocation == null) { error = "Cannot find given icon file."; } else { - ImageData data = loadImage(iconLocation); - if (data != null) { - KRectangle figure = _kContainerRenderingExtensions.addRectangle(rendering); - _kRenderingExtensions.setInvisible(figure, true); - KGridPlacementData figurePlacement = _kRenderingExtensions.setGridPlacementData(figure, data.width, data.height); - _kRenderingExtensions.to( - _kRenderingExtensions.from( - figurePlacement, - _kRenderingExtensions.LEFT, 3, 0, - _kRenderingExtensions.TOP, 0, 0), - _kRenderingExtensions.RIGHT, 3, 0, - _kRenderingExtensions.BOTTOM, 3, 0); - - KRectangle icon = _kContainerRenderingExtensions.addRectangle(figure); - _kRenderingExtensions.setInvisible(icon, true); - _kContainerRenderingExtensions.addImage(icon, data); - _kRenderingExtensions.setPointPlacementData(icon, - _kRenderingExtensions.createKPosition( - _kRenderingExtensions.LEFT, 0, 0.5f, - _kRenderingExtensions.TOP, 0, 0.5f), - _kRenderingExtensions.H_CENTRAL, _kRenderingExtensions.V_CENTRAL, 0, - 0, data.width, data.height); - } - if (error != null) { - var errorText = _kContainerRenderingExtensions.addText(rendering, "Icon not found!\n"+error); - _kRenderingExtensions.setForeground(errorText, Colors.RED); - _kRenderingExtensions.setFontBold(errorText, true); - _kRenderingExtensions.setSurroundingSpaceGrid(errorText, 8, 0); - } + /* + * This code was disabled because it cannot be compiled for the language server with Gradle. + * As soon as the Klighd API is extended to support URI-based images in both Eclipse and VSCode, + * this code should be reactivated and adapted. + * See: https://github.com/kieler/KLighD/issues/146 + */ +// ImageData data = loadImage(iconLocation); +// if (data != null) { +// KRectangle figure = _kContainerRenderingExtensions.addRectangle(rendering); +// _kRenderingExtensions.setInvisible(figure, true); +// KGridPlacementData figurePlacement = _kRenderingExtensions.setGridPlacementData(figure, data.width, data.height); +// _kRenderingExtensions.to( +// _kRenderingExtensions.from( +// figurePlacement, +// _kRenderingExtensions.LEFT, 3, 0, +// _kRenderingExtensions.TOP, 0, 0), +// _kRenderingExtensions.RIGHT, 3, 0, +// _kRenderingExtensions.BOTTOM, 3, 0); +// +// KRectangle icon = _kContainerRenderingExtensions.addRectangle(figure); +// _kRenderingExtensions.setInvisible(icon, true); +// _kContainerRenderingExtensions.addImage(icon, data); +// _kRenderingExtensions.setPointPlacementData(icon, +// _kRenderingExtensions.createKPosition( +// _kRenderingExtensions.LEFT, 0, 0.5f, +// _kRenderingExtensions.TOP, 0, 0.5f), +// _kRenderingExtensions.H_CENTRAL, _kRenderingExtensions.V_CENTRAL, 0, +// 0, data.width, data.height); +// } +// if (error != null) { +// var errorText = _kContainerRenderingExtensions.addText(rendering, "Icon not found!\n"+error); +// _kRenderingExtensions.setForeground(errorText, Colors.RED); +// _kRenderingExtensions.setFontBold(errorText, true); +// _kRenderingExtensions.setSurroundingSpaceGrid(errorText, 8, 0); +// } } } } - private ImageData loadImage(final java.net.URI uri) { - try { - if (cache.containsKey(uri)) { - return cache.get(uri); - } - synchronized (LOADER) { - InputStream inStream = null; - try { - inStream = uri.toURL().openStream(); - ImageData[] data = LOADER.load(inStream); - if (data != null && data.length > 0) { - ImageData img = data[0]; - cache.put(uri, img); - return img; - } else { - error = "Could not load icon image."; - return null; - } - } finally { - if (inStream != null) { - inStream.close(); - } - } - } - } catch (Exception ex) { - ex.printStackTrace(); - error = "Could not load icon image."; - return null; - } - } +// private ImageData loadImage(final java.net.URI uri) { +// try { +// if (cache.containsKey(uri)) { +// return cache.get(uri); +// } +// synchronized (LOADER) { +// InputStream inStream = null; +// try { +// inStream = uri.toURL().openStream(); +// ImageData[] data = LOADER.load(inStream); +// if (data != null && data.length > 0) { +// ImageData img = data[0]; +// cache.put(uri, img); +// return img; +// } else { +// error = "Could not load icon image."; +// return null; +// } +// } finally { +// if (inStream != null) { +// inStream.close(); +// } +// } +// } +// } catch (Exception ex) { +// ex.printStackTrace(); +// error = "Could not load icon image."; +// return null; +// } +// } } diff --git a/org.lflang.ide/build.gradle b/org.lflang.ide/build.gradle index 8e89890fcf..e755cf8529 100644 --- a/org.lflang.ide/build.gradle +++ b/org.lflang.ide/build.gradle @@ -1,4 +1,3 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar dependencies { implementation project(':org.lflang') implementation "org.eclipse.xtext:org.eclipse.xtext.ide:${xtextVersion}" @@ -6,47 +5,3 @@ dependencies { } apply plugin: 'application' -apply plugin: 'com.github.johnrengelman.shadow' - -task generateLanguageServer { - description 'Creates a jar file that implements a language server.' - - apply plugin: 'java' - apply plugin: 'application' - apply plugin: 'com.github.johnrengelman.shadow' - mainClassName = "org.eclipse.xtext.ide.server.ServerLauncher" - - shadowJar { - classifier = 'ls' - minimize() { - exclude(dependency('log4j:log4j:.*')) - exclude(dependency('org.eclipse.xtext:.*ide:.*')) - } - - exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'schema/*', - '.options', '.api_description', '*.profile', '*.html', 'about.*', 'about_files/*', 'ant_tasks/*', - 'plugin.xml', 'modeling32.png', 'xtext32.png', 'systembundle.properties', 'profile.list') - - transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer){ - resource = 'plugin.properties' - } - } - - compileJava { - options.compilerArgs << '-Xlint:unchecked' - } -} - -generateLanguageServer.finalizedBy shadowJar - -task testJar(type: ShadowJar) { - mainClassName = "org.eclipse.xtext.ide.server.ServerLauncher" - //minimize() // Minimizing might cause problems because it could delete classes that are not referenced but loaded by name (service loader) - from(project.convention.getPlugin(JavaPluginConvention).sourceSets.main.output) - configurations = [project.configurations.runtime] - exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA','schema/*', - '.options', '.api_description', '*.profile', '*.html', 'about.*', 'about_files/*', - 'plugin.xml', 'modeling32.png', 'systembundle.properties', 'profile.list') - classifier = 'ls' - append('plugin.properties') -} diff --git a/org.lflang.lds/.project b/org.lflang.lds/.project deleted file mode 100644 index 253f28ebf7..0000000000 --- a/org.lflang.lds/.project +++ /dev/null @@ -1,11 +0,0 @@ - - - org.lflang.updatesite - - - - - - - - diff --git a/org.lflang.lds/category.xml b/org.lflang.lds/category.xml deleted file mode 100644 index 296073d71a..0000000000 --- a/org.lflang.lds/category.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Artificial update site for the Lingua Franca language server with diagrams. - - - - diff --git a/org.lflang.lds/pom.xml b/org.lflang.lds/pom.xml deleted file mode 100644 index b23e4d43ac..0000000000 --- a/org.lflang.lds/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - - ../pom.xml - org.lflang - lf - 0.3.1-SNAPSHOT - - - org.lflang.lds - eclipse-repository - - Lingua Franca Language and Diagram Server - - - ${basedir}/category.xml - ${project.build.directory}/repository/plugins - ${basedir}/uberjar.py - lflang-lds - org.lflang.diagram.lsp.LanguageDiagramServer - ${project.build.directory}/exe - - - - - - - - org.eclipse.tycho - tycho-p2-repository-plugin - ${tychoVersion} - - true - - true - - - - - org.codehaus.mojo - exec-maven-plugin - ${execMavenPluginVersion} - - - package - - exec - - - - - python3 - ${project.build.directory} - - ${python.script} - --noswt - ${update.site.jars} - ${executableName} - ${mainClass} - ${python.script.output} - ${project.build.directory} - - - - - - diff --git a/org.lflang.lds/uberjar.py b/org.lflang.lds/uberjar.py deleted file mode 100644 index 1e4d16e2a0..0000000000 --- a/org.lflang.lds/uberjar.py +++ /dev/null @@ -1,392 +0,0 @@ -# KIELER - Kiel Integrated Environment for Layout Eclipse RichClient -# http://www.informatik.uni-kiel.de/rtsys/kieler/ -# -# Copyright 2019 by -# + Kiel University -# + Department of Computer Science -# + Real-Time and Embedded Systems Group -# -# This code is provided under the terms of the Eclipse Public License (EPL). -# See the file epl-v10.html for the license text. - -# -# This script bundles a self-contained eclipse update site into an executable uber-jar (no shading!) and several platform specific executable scripts bundling the jar. -# Author: Alexander Schulz-Rosengarten -# - -# General Documentation: -# The idea of having an executable non-eclipse application with eclipse plugins is to bundle them into a uber/fat jar containing all dependencies. -# Usually this job is done by the maven-shade-plugin. However, since we build our plugins with tycho and have a defined target platform for dependency resolution, this system is incompatible with maven-shade. maven-shade would require to redefine each dependency explicitly and from a maven repository. -# Hence, we build a self-contained update side using tycho, this way we have all our dependencies automatically and correctly resolve without any redefinitions and we can build only specific plugins into the executable. -# Then this script bundles the jars in the update side into one uber jar. -# In contrast to maven-shade this script cannot 'shade' dependencies. If this should be necessary in the future, it might be a solution to process the update side by another build run using maven-shade and some pom file generated by a script to correctly defining the dependencies to include. - -from __future__ import print_function # python3 print - -import os -import stat -import sys -import shutil -import argparse -import re -from subprocess import check_call -from fnmatch import fnmatch -from os.path import isfile, isdir, join, abspath, relpath, dirname, basename - -IGNORED_JARS = [ - 'org.apache.ant*', - # The following libraries are part of the org.jetbrains.kotlin.bundled-compiler plugin but are not required at runtime. - 'kotlin-compiler.jar', - 'intellij-core-analysis.jar', - 'kotlin-plugin-parts.jar', - 'kotlin-script-runtime.jar', - 'kotlin-scripting-compiler.jar', - 'ide-dependencies.jar', - 'kotlin-scripting-compiler-impl.jar', - 'kotlin-scripting-common.jar', - 'kotlin-scripting-jvm.jar', - 'ide-common.jar' -] -IGNORE_NESTED_JARS = [ -] -IGNORED_FILES = [ - 'org/*/*.java', - 'com/*/*.java', - 'de/*/*.java', - 'module-info.class', - '*._trace', - '*.g', - '*.mwe2', - '*.xtext', - '*.genmodel', - '*.ecore', - '*.ecorediag', - '*.html', - '*.profile', - '.api_description', - '.options', - 'log4j.properties', - 'about.*', - 'about_*', - 'about_files/*', - 'cheatsheets/*', - 'META-INF/*.DSA', - 'META-INF/*.RSA', - 'META-INF/*.SF', - 'META-INF/changelog.txt', - 'META-INF/DEPENDENCIES', - 'META-INF/eclipse.inf', - 'META-INF/INDEX.LIST', - 'META-INF/MANIFEST.MF', # not sure if we have to merge the content somehow? - 'META-INF/maven/*', - 'META-INF/NOTICE.txt', - 'META-INF/NOTICE', - 'META-INF/p2.inf', - 'META-INF/versions/*/module-info.class', - 'OSGI-INF/l10n/bundle.properties', - 'docs/*', - '*readme.txt', - 'plugin.xml', - 'schema/*', - 'profile.list', - 'systembundle.properties', - 'version.txt', - 'xtend-gen/*', -] -APPEND_MERGE = [ - 'plugin.properties', - 'META-INF/services/*', - 'META-INF/LICENSE.txt', - 'META-INF/LICENSE', -] -IGNORE_MERGE = [ - 'eclipse32.png', - 'modeling32.png', - 'icons/*.png', # Assuming icons are always the same if they have the same name or de.* overrides org.* - 'icons/*.gif', - 'epl-v10.html', - 'org/osgi/service/log/*', # known duplicate in org.eclipse.osgi and org.eclipse.osgi.services, - 'META-INF/AL*', - 'META-INF/LGPL*', - 'META-INF/GPL*', -] - -# Special klighd handling -KLIGHD_JARS_BLACKLIST = [ - 'org.eclipse.ui*', - 'org.eclipse.e4*', - 'org.eclipse.*.ui*', -] -KLIGHD_JARS_WHITELIST = [ - 'org.eclipse.ui.workbench_*', - 'org.eclipse.ui.ide_*', # For some reason IStorageEditorInput is required -] -KLIGHD_IGNORED_FILES = [ - 'org/eclipse/ui/[!I]*', # Keep Interfaces for Klighd! - 'org/eclipse/ui/*/*', - 'org.eclipse.ui.ide*/icons/*', - 'fragment.properties', -] -klighd_swt = {} - -def windows_safe_abspath(path): - """Returns an absolute path that will not be invalidated by the - Windows maximum path length. - """ - if sys.platform == 'win32': - return '\\\\?\\' + abspath(path) - return abspath(path) - -def main(args): - print('-- Creating uber jar --') - - extracted = abspath(join(args.build, 'extracted')) - merged = abspath(join(args.build, 'merged')) - - def assert_is_dir(s): - if not isdir(s): - stop('%s is not a directory or does not exist' % s) - - # Check input - assert_is_dir(args.source) - - # Create build folders - if isdir(extracted): - shutil.rmtree(extracted) - else: - os.mkdir(extracted) - if isdir(merged): - shutil.rmtree(merged) - else: - os.mkdir(merged) - - target_dir = abspath(args.target) - - # Check klighd - jars = os.listdir(args.source) - klighd = any(jar.startswith('de.cau.cs.kieler.klighd') for jar in jars) - if klighd: - print('Detected Klighd. Activated special handling of Eclipse UI and SWT dependencies.') - - # Extract - conflicts = extract(args, extracted, merged, klighd) - if conflicts and not args.ignore_conflicts: - stop('Stopping build due to merge conflicts.') - - # Bundle into jar - jar = bundle(args, target_dir, merged, klighd) - - # Wrapper scripts - if args.scripts: - create_standalone_scripts(args, jar, target_dir,klighd) - -def extract(args, extracted, merged, klighd): - conflicts = False - jars = sorted(os.listdir(args.source)) - processed_jars = [] # Tuples of plugin name and jar - for jar in jars: - if not jar.endswith('.jar') or any(fnmatch(jar, ign) for ign in IGNORED_JARS): - print('Skipping file:', jar) - continue - elif klighd and any(fnmatch(jar, ign) for ign in KLIGHD_JARS_BLACKLIST) and not any(fnmatch(jar, req) for req in KLIGHD_JARS_WHITELIST): - print('Skipping file (special klighd handling):', jar) - continue - elif jar.split("_")[0] in (p[0] for p in processed_jars): - print('Multiple versions of the same plugin detected.') - print('WARNING: This script does not support shading. Only the lower version of this plugin will be used (%s). This will cause runtime errors if any plugin requires a higher version API.' % next((p[1] for p in processed_jars if p[0] == jar.split("_")[0]), None)) - print('Skipping file:', jar) - continue - else: - print('Extracting jar:', jar) - target = abspath(join(extracted, jar[:-4])) - if not isdir(target): - os.makedirs(target) - - # Unpack jar - check_call([args.jar, 'xf', abspath(join(args.source, jar))], cwd=target) - - if klighd and jar.startswith('org.eclipse.swt.'): # Do not merge swt fragments - if 'gtk.linux.x86_64' in jar: - klighd_swt['linux'] = target - elif 'win32.win32.x86_64' in jar: - klighd_swt['win'] = target - elif 'cocoa.macosx.x86_64' in jar: - klighd_swt['osx'] = target - else: - stop('Unknown platform-specific SWT fragment: ', jar) - # Remove unwanted files from fragment directory - for root, dirs, files in os.walk(target): - for file in (relpath(join(root, f), target) for f in files): - if any(fnmatch(file, pattern) for pattern in IGNORED_FILES) or any(fnmatch(file, pattern) for pattern in KLIGHD_IGNORED_FILES): - os.remove(join(target, file)) - else: # Merge content - if not any(fnmatch(jar, ign) for ign in IGNORE_NESTED_JARS): - # Append nested jars for later unpacking - jars.extend(j for j in handleNestedJarsOnClasspath(target, args.source) if j not in jars) - # Merge jar content into single folder - for root, dirs, files in os.walk(target): - for file in (relpath(join(root, f), target) for f in files): - if any(fnmatch(file, pattern) for pattern in IGNORED_FILES): - continue #skip - if klighd and any(fnmatch(file, pattern) for pattern in KLIGHD_IGNORED_FILES): - continue #skip - - src = join(target, file) - dest = join(merged, file) - - if isfile(dest): # potential conflict - if any(fnmatch(file, match) for match in APPEND_MERGE): # merge by append - with open(src, 'r') as i: - with open(dest, 'a') as o: - o.write('\n') - o.write(i.read()) - elif any(fnmatch(file, match) for match in IGNORE_MERGE): # merge by ignoring overriders, assuming identical files ;) - pass - else: - errPrint('[ERROR] Could not merge', jar, 'Conflicting file:', file) - conflicts = True - else: - os.renames(windows_safe_abspath(src), windows_safe_abspath(dest)) - processed_jars.append((jar.split("_")[0], jar)) - return conflicts - -def handleNestedJarsOnClasspath(dir, jars_dir): - jars = [] - manifest = join(dir, join('META-INF', 'MANIFEST.MF')) - if isfile(manifest): - with open(manifest, 'r') as file: - lines = file.readlines() - classpath = None - for line in lines: - if 'Bundle-ClassPath:' in line: # start of classpath - startCP = line[17:].strip() - classpath = startCP if startCP else " " # assure truthy content if found - elif classpath and ':' in line: # end of classpath - break - elif classpath: # continue classpath collection - classpath += line.strip() - if classpath: - for cp in classpath.split(','): - cpFile = cp.strip() - if cpFile and cpFile != '.' and '.jar' in cpFile: - jarFile = join(dir, cpFile) - if isfile(jarFile): - print('Found nested jar on bundle class path: ', cpFile) - dest = join(jars_dir, basename(jarFile)) - if isfile(dest): - continue # The nested jar is already in the directory - # and does not need to be added again. - os.rename(jarFile, dest) # Move to input folder - jars.append(basename(jarFile)) - else: - print('[Warning] Could not find file for nested jar on bundle class path: ', cpFile) - return jars - - -def bundle(args, target_dir, merged, klighd): - jar = join(target_dir, args.name + '.jar') - print('Creating jar:', relpath(jar, target_dir)) - if not isdir(dirname(jar)): - os.makedirs(dirname(jar)) - - check_call([args.jar, 'cfe', jar, args.main, '.'], cwd=merged) - - if klighd and not args.noswt: # Include SWT - jars = {} - for platform in klighd_swt.keys(): - pjar = jar[:-4] + '.' + platform + '.jar' - print('Creating jar:', relpath(pjar, target_dir)) - - shutil.copy(jar, pjar) # copy SWT-less base jar - check_call([args.jar, 'uf', pjar, '.'], cwd=klighd_swt[platform]) # Bundle platform-spefic SWT into new platform-spefic jar - - jars[platform] = pjar - - print('Removing jar:', relpath(jar, target_dir)) - os.remove(jar) # remove SWT-less base jar - return jars - else: - return jar - -def create_standalone_scripts(args, jar, target_dir, klighd): - # This is some magic found in the depth of the internet by chsch - print('-- Creating standalone scripts --') - java9_options = ' --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED' - - if klighd and not args.noswt: - jar_linux = jar['linux'] - jar_win = jar['win'] - jar_osx = jar['osx'] - else: - jar_linux = jar_win = jar_osx = jar - - # linux - if jar_linux: - with open(jar_linux, 'rb') as jar_file: - code = jar_file.read() - linux_cmd = '#!/usr/bin/env bash\nexec java -Djava.system.class.loader=de.cau.cs.kieler.kicool.cli.CLILoader -Xmx512m %s -jar $0 "$@"\n' - - with open(join(target_dir, args.name + '-linux'), 'wb') as file: - write_script(file, linux_cmd % java9_options, code) - if args.java8: - with open(join(target_dir, args.name + '-linuxJava8'), 'wb') as file: - write_script(file, linux_cmd % '', code) - - # windows - if jar_win: - with open(jar_win, 'rb') as jar_file: - code = jar_file.read() - win_cmd = 'java -Djava.system.class.loader=de.cau.cs.kieler.kicool.cli.CLILoader -Xmx512m %s -jar %%0 %%* \r\n exit /b %%errorlevel%%\r\n' # escaped percent sign because of format string! - - with open(join(target_dir, args.name + '-win.bat'), 'wb') as file: - write_script(file, win_cmd % java9_options, code) - if args.java8: - with open(join(target_dir, args.name + '-winJava8.bat'), 'wb') as file: - write_script(file, win_cmd % '', code) - - # osx - if jar_osx: - with open(jar_osx, 'rb') as jar_file: - code = jar_file.read() - osx_cmd = '#!/usr/bin/env bash\nexec java -Djava.system.class.loader=de.cau.cs.kieler.kicool.cli.CLILoader -XstartOnFirstThread -Xmx512m %s -jar $0 "$@" \n' - - with open(join(target_dir, args.name + '-osx'), 'wb') as file: - write_script(file, osx_cmd % java9_options, code) - if args.java8: - with open(join(target_dir, args.name + '-osxJava8'), 'wb') as file: - write_script(file, osx_cmd % '', code) - -def write_script(file, command, code): - print('Creating script', basename(file.name)) - file.write(command) - file.write(code) - flags = os.fstat(file.fileno()).st_mode - flags |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - os.fchmod(file.fileno(), stat.S_IMODE(flags)) - -def stop(msg): - errPrint('[ERROR] ' + msg) - sys.exit(2) - -def errPrint(*args, **kwargs): - sys.stdout.flush() # ensure the context is clear - print(*args, file=sys.stderr, **kwargs) - sys.stderr.flush() - -if __name__ == '__main__': - argParser = argparse.ArgumentParser(description='This script bundles a self-contained eclipse update site into an executable uber-jar (no shading!) and several platform specific executable scripts bundling the jar.') - argParser.add_argument('-s', dest='scripts', action='store_true', help='create platform specific standalone scripts of the jar') - argParser.add_argument('-jar', default='jar', help='override jar command to adjust java version, e.g. /usr/lib/jvm/java-11-openjdk-amd64/bin/jar') - argParser.add_argument('--java8', dest='java8', action='store_true', help='activate Java 8 support') - argParser.add_argument('--noswt', dest='noswt', action='store_true', help='skips bundling platform specific SWT dependencies.') - argParser.add_argument('--ignore-conflicts', dest='ignore_conflicts', action='store_true', help='prevents failing if merge fail due to a conflict.') - argParser.add_argument('source', help='directory containing all plugins that should be bundled (self-contained update site)') - argParser.add_argument('name', help='name of the generated executable jar/script') - argParser.add_argument('main', help='main class of the generated jar') - argParser.add_argument('target', help='target directory to store generated jar/ and scripts') - argParser.add_argument('build', help='directory for storing intermediate results') - try: - main(argParser.parse_args()) - except KeyboardInterrupt: - print('\nAbort') - sys.exit(0) diff --git a/pom.xml b/pom.xml index f6a4bf37c4..b8850e3dbc 100644 --- a/pom.xml +++ b/pom.xml @@ -63,18 +63,6 @@ org.lflang.targetplatform - - lds - - - org.lflang - org.lflang.ide - org.lflang.diagram - - org.lflang.lds - org.lflang.targetplatform - - diff --git a/settings.gradle b/settings.gradle index 3e48c953bb..a6d734cb8f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,5 @@ include 'org.lflang' +include 'org.lflang.ide' +include 'org.lflang.diagram' include 'org.lflang.cli' include 'org.lflang.tests'