From 3e1d1055d13b55a4bce8288a901299d681185448 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Thu, 18 Jan 2024 16:09:11 +0100 Subject: [PATCH 01/77] use safe abs in loop opts (cherry picked from commit 28b5bd64aaa9e7dad68acc7ddccb466e0dbf43fb) --- .../loop/phases/LoopPredicationPhase.java | 2 ++ .../jdk/graal/compiler/nodes/loop/LoopEx.java | 15 +++++++-- .../phases/common/util/LoopUtility.java | 33 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java index 7c44206b9671..f6769e558689 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java @@ -114,6 +114,8 @@ protected void run(StructuredGraph graph, MidTierContext context) { final boolean inverted = loop.counted().isInverted(); if ((((IntegerStamp) counter.valueNode().stamp(NodeView.DEFAULT)).getBits() == 32) && !counted.isUnsignedCheck() && + // math.abs can overflow here but only to min again which is + // never == 1 ((condition != NE && condition != EQ) || (counter.isConstantStride() && Math.abs(counter.constantStride()) == 1)) && (loop.loopBegin().isMainLoop() || loop.loopBegin().isSimpleLoop())) { NodeIterable guards = loop.whole().nodes().filter(GuardNode.class); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java index 2a5ad5e71fc2..48e32d0d38e2 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java @@ -79,6 +79,7 @@ import jdk.graal.compiler.nodes.extended.ValueAnchorNode; import jdk.graal.compiler.nodes.util.GraphUtil; import jdk.graal.compiler.phases.common.CanonicalizerPhase; +import jdk.graal.compiler.phases.common.util.LoopUtility; public class LoopEx { protected final Loop loop; @@ -334,7 +335,7 @@ public boolean detectCounted() { // signed: i < MAX_INT } else if (limitStamp.asConstant() != null && limitStamp.asConstant().asLong() == counterStamp.unsignedUpperBound()) { unsigned = true; - } else if (!iv.isConstantStride() || Math.abs(iv.constantStride()) != 1 || initStamp.upperBound() > limitStamp.lowerBound()) { + } else if (!iv.isConstantStride() || !absStrideIsOne(iv) || initStamp.upperBound() > limitStamp.lowerBound()) { return false; } } else if (iv.direction() == InductionVariable.Direction.Down) { @@ -342,7 +343,7 @@ public boolean detectCounted() { // signed: MIN_INT > i } else if (limitStamp.asConstant() != null && limitStamp.asConstant().asLong() == counterStamp.unsignedLowerBound()) { unsigned = true; - } else if (!iv.isConstantStride() || Math.abs(iv.constantStride()) != 1 || initStamp.lowerBound() < limitStamp.upperBound()) { + } else if (!iv.isConstantStride() || !absStrideIsOne(iv) || initStamp.lowerBound() < limitStamp.upperBound()) { return false; } } else { @@ -389,6 +390,16 @@ public boolean detectCounted() { return false; } + public static boolean absStrideIsOne(InductionVariable limitCheckedIV) { + final long absStride; + try { + absStride = LoopUtility.abs(limitCheckedIV.constantStride(), IntegerStamp.getBits(limitCheckedIV.strideNode().stamp(NodeView.DEFAULT))); + } catch (ArithmeticException e) { + return false; + } + return absStride == 1; + } + public boolean isCfgLoopExit(AbstractBeginNode begin) { HIRBlock block = data.getCFG().blockFor(begin); return loop.getDepth() > block.getLoopDepth() || loop.isNaturalExit(block); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java index 8fe102300bab..c3cfa1b04fbd 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java @@ -29,6 +29,7 @@ import jdk.graal.compiler.core.common.cfg.Loop; import jdk.graal.compiler.core.common.type.IntegerStamp; import jdk.graal.compiler.core.common.type.Stamp; +import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.Graph.NodeEvent; import jdk.graal.compiler.graph.Graph.NodeEventScope; import jdk.graal.compiler.graph.Node; @@ -54,6 +55,38 @@ public class LoopUtility { + public static boolean canTakeAbs(long l, int bits) { + try { + abs(l, bits); + return true; + } catch (ArithmeticException e) { + return false; + } + } + + /** + * Compute {@link Math#abs(long)} for the given arguments and the given bit size. Throw a + * {@link ArithmeticException} if the abs operation would overflow. + */ + public static long abs(long l, int bits) throws ArithmeticException { + if (bits == 32) { + if (l == Integer.MIN_VALUE) { + throw new ArithmeticException("Abs on Integer.MIN_VALUE would cause an overflow because abs(Integer.MIN_VALUE) = Integer.MAX_VALUE + 1 which does not fit in int (32bits)"); + } else { + final int i = (int) l; + return Math.abs(i); + } + } else if (bits == 64) { + if (l == Long.MIN_VALUE) { + throw new ArithmeticException("Abs on Long.MIN_VALUE would cause an overflow because abs(Long.MIN_VALUE) = Long.MAX_VALUE + 1 which does not fit in int (32bits)"); + } else { + return Math.abs(l); + } + } else { + throw GraalError.shouldNotReachHere("Must be one of java's core datatypes int/long but is " + bits); + } + } + /** * Determine if the def can use node {@code use} without the need for value proxies. This means * there is no loop exit between the schedule point of def and use that would require a From 4e6249a2c0aa058c55133bf8f11c232c89b658b1 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Tue, 23 Jan 2024 13:47:56 +0100 Subject: [PATCH 02/77] fix comment (cherry picked from commit 83c699edbfc6af7b6effeb3ad536fbc6531edf3a) --- .../jdk/graal/compiler/phases/common/util/LoopUtility.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java index c3cfa1b04fbd..f025087619d8 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/util/LoopUtility.java @@ -71,14 +71,14 @@ public static boolean canTakeAbs(long l, int bits) { public static long abs(long l, int bits) throws ArithmeticException { if (bits == 32) { if (l == Integer.MIN_VALUE) { - throw new ArithmeticException("Abs on Integer.MIN_VALUE would cause an overflow because abs(Integer.MIN_VALUE) = Integer.MAX_VALUE + 1 which does not fit in int (32bits)"); + throw new ArithmeticException("Abs on Integer.MIN_VALUE would cause an overflow because abs(Integer.MIN_VALUE) = Integer.MAX_VALUE + 1 which does not fit in int (32 bits)"); } else { final int i = (int) l; return Math.abs(i); } } else if (bits == 64) { if (l == Long.MIN_VALUE) { - throw new ArithmeticException("Abs on Long.MIN_VALUE would cause an overflow because abs(Long.MIN_VALUE) = Long.MAX_VALUE + 1 which does not fit in int (32bits)"); + throw new ArithmeticException("Abs on Long.MIN_VALUE would cause an overflow because abs(Long.MIN_VALUE) = Long.MAX_VALUE + 1 which does not fit in long (64 bits)"); } else { return Math.abs(l); } From 212002dcab2af01e5d58f07fbf3f11f357c5230d Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Tue, 23 Jan 2024 13:55:27 +0100 Subject: [PATCH 03/77] loop ex: allow overflow in math.abs for stride !=1 checks, it does not matter, in case of overflow the value is still different (cherry picked from commit ac0fc684c9b78b337873d5789d8886cd6a93cea9) --- .../src/jdk/graal/compiler/nodes/loop/LoopEx.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java index 48e32d0d38e2..7b349523b243 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopEx.java @@ -79,7 +79,6 @@ import jdk.graal.compiler.nodes.extended.ValueAnchorNode; import jdk.graal.compiler.nodes.util.GraphUtil; import jdk.graal.compiler.phases.common.CanonicalizerPhase; -import jdk.graal.compiler.phases.common.util.LoopUtility; public class LoopEx { protected final Loop loop; @@ -391,13 +390,12 @@ public boolean detectCounted() { } public static boolean absStrideIsOne(InductionVariable limitCheckedIV) { - final long absStride; - try { - absStride = LoopUtility.abs(limitCheckedIV.constantStride(), IntegerStamp.getBits(limitCheckedIV.strideNode().stamp(NodeView.DEFAULT))); - } catch (ArithmeticException e) { - return false; - } - return absStride == 1; + /* + * While Math.abs can overflow for MIN_VALUE it is fine here. In case of overflow we still + * get a value != 1 (namely MIN_VALUE again). Overflow handling for the limit checked IV is + * done in CountedLoopInfo and is an orthogonal issue. + */ + return Math.abs(limitCheckedIV.constantStride()) == 1; } public boolean isCfgLoopExit(AbstractBeginNode begin) { From 917983db31ba28ccaafa3197574e75127692a4b6 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Fri, 26 Jan 2024 14:30:23 +0100 Subject: [PATCH 04/77] reuse loopex.absStrideIsOne (cherry picked from commit 429b3f9fb983e98bd87b8d440c43195e4d75f0d1) --- .../graal/compiler/loop/phases/LoopPredicationPhase.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java index f6769e558689..4fbf9d85c95e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/LoopPredicationPhase.java @@ -112,11 +112,8 @@ protected void run(StructuredGraph graph, MidTierContext context) { final InductionVariable counter = counted.getLimitCheckedIV(); final Condition condition = ((CompareNode) counted.getLimitTest().condition()).condition().asCondition(); final boolean inverted = loop.counted().isInverted(); - if ((((IntegerStamp) counter.valueNode().stamp(NodeView.DEFAULT)).getBits() == 32) && - !counted.isUnsignedCheck() && - // math.abs can overflow here but only to min again which is - // never == 1 - ((condition != NE && condition != EQ) || (counter.isConstantStride() && Math.abs(counter.constantStride()) == 1)) && + if ((((IntegerStamp) counter.valueNode().stamp(NodeView.DEFAULT)).getBits() == 32) && !counted.isUnsignedCheck() && + ((condition != NE && condition != EQ) || (counter.isConstantStride() && LoopEx.absStrideIsOne(counter))) && (loop.loopBegin().isMainLoop() || loop.loopBegin().isSimpleLoop())) { NodeIterable guards = loop.whole().nodes().filter(GuardNode.class); if (LoopPredicationMainPath.getValue(graph.getOptions())) { From 2252a160002cd59f401b9504d7114f1eefff280e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Pejovi=C4=87?= Date: Mon, 5 Feb 2024 11:29:51 +0100 Subject: [PATCH 05/77] Report error if building static executable without musl libc (cherry picked from commit bad33144a806500eef42df01cc46deaa8cb83eb8) --- .../src/com/oracle/svm/core/SubstrateOptions.java | 4 ++++ .../svm/core/option/ValidateImageBuildOptionsFeature.java | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 4cb22f602036..df2b6ff5b066 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -108,6 +108,10 @@ public class SubstrateOptions { if (!Platform.includedIn(Platform.LINUX.class)) { throw UserError.invalidOptionValue(key, key.getValue(), "Building static executable images is currently only supported on Linux. Remove the '--static' option or build on a Linux machine"); } + if (!LibCBase.targetLibCIs(MuslLibC.class)) { + throw UserError.invalidOptionValue(key, key.getValue(), + "Building static executable images is only supported with musl libc. Remove the '--static' option or add the '--libc=musl' option."); + } }); @APIOption(name = "libc")// diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/ValidateImageBuildOptionsFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/ValidateImageBuildOptionsFeature.java index b7fea207a8ce..c20c7d1b8041 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/ValidateImageBuildOptionsFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/option/ValidateImageBuildOptionsFeature.java @@ -25,15 +25,16 @@ package com.oracle.svm.core.option; import org.graalvm.collections.UnmodifiableMapCursor; -import jdk.graal.compiler.options.OptionKey; -import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; + +import jdk.graal.compiler.options.OptionKey; @AutomaticallyRegisteredFeature public class ValidateImageBuildOptionsFeature implements InternalFeature { @Override - public void afterRegistration(AfterRegistrationAccess access) { + public void beforeAnalysis(BeforeAnalysisAccess access) { UnmodifiableMapCursor, Object> cursor = RuntimeOptionValues.singleton().getMap().getEntries(); while (cursor.advance()) { validate(cursor.getKey()); From c809f5be530289f01455b80f41795ce581039d79 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Wed, 7 Feb 2024 17:13:15 +0100 Subject: [PATCH 06/77] Fix a deadlock in IsolateAwareTruffleCompiler.tearDownIsolateOnShutdown. --- .../oracle/svm/core/jdk/RuntimeSupport.java | 2 +- .../isolated/IsolateAwareTruffleCompiler.java | 39 ++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java index d6ea31d654f0..211d550f8747 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RuntimeSupport.java @@ -133,7 +133,7 @@ public static void executeInitializationHooks() { /** * Adds a hook which will execute during isolate tear-down. Note it is possible for the - * {@link #tearDownHooks} to called without the {@link #initializationHooks} executing first. + * {@link #tearDownHooks} to be called without the {@link #initializationHooks} executing first. */ public void addTearDownHook(Hook tearDownHook) { addHook(tearDownHooks, tearDownHook); diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java index eb7f9ae904b9..3d21d1870a9b 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/isolated/IsolateAwareTruffleCompiler.java @@ -28,13 +28,6 @@ import java.io.StringWriter; import java.util.concurrent.atomic.AtomicBoolean; -import jdk.graal.compiler.core.common.CompilationIdentifier; -import jdk.graal.compiler.core.common.SuppressFBWarnings; -import jdk.graal.compiler.nodes.PauseNode; -import jdk.graal.compiler.truffle.PartialEvaluator; -import jdk.graal.compiler.truffle.TruffleCompilation; -import jdk.graal.compiler.truffle.phases.TruffleTier; -import jdk.graal.compiler.word.Word; import org.graalvm.nativeimage.CurrentIsolate; import org.graalvm.nativeimage.Isolate; import org.graalvm.nativeimage.IsolateThread; @@ -66,6 +59,14 @@ import com.oracle.truffle.compiler.TruffleCompilationTask; import com.oracle.truffle.compiler.TruffleCompilerListener; +import jdk.graal.compiler.core.common.CompilationIdentifier; +import jdk.graal.compiler.core.common.SuppressFBWarnings; +import jdk.graal.compiler.nodes.PauseNode; +import jdk.graal.compiler.truffle.PartialEvaluator; +import jdk.graal.compiler.truffle.TruffleCompilation; +import jdk.graal.compiler.truffle.phases.TruffleTier; +import jdk.graal.compiler.word.Word; + public class IsolateAwareTruffleCompiler implements SubstrateTruffleCompiler { private static final Word ISOLATE_INITIALIZING = WordFactory.signed(-1); @@ -133,10 +134,18 @@ protected CompilerIsolateThread beforeCompilation() { Isolate isolate = getSharedIsolate(); if (isolate.isNull()) { if (sharedIsolate.compareAndSet(WordFactory.nullPointer(), (Isolate) ISOLATE_INITIALIZING)) { - CompilerIsolateThread thread = IsolatedGraalUtils.createCompilationIsolate(); - Runtime.getRuntime().addShutdownHook(new Thread(this::sharedIsolateShutdown)); - sharedIsolate.set(Isolates.getIsolate(thread)); - return thread; // (already attached) + try { + /* Adding the shutdown hook may fail if a shutdown is already in progress. */ + Runtime.getRuntime().addShutdownHook(new Thread(this::sharedIsolateShutdown)); + CompilerIsolateThread thread = IsolatedGraalUtils.createCompilationIsolate(); + sharedIsolate.set(Isolates.getIsolate(thread)); + return thread; // (already attached) + } catch (Throwable e) { + /* Reset the value so that the teardown hook doesn't hang. */ + assert sharedIsolate.get().equal(ISOLATE_INITIALIZING); + sharedIsolate.set(WordFactory.nullPointer()); + throw e; + } } isolate = getSharedIsolate(); assert isolate.isNonNull(); @@ -155,9 +164,11 @@ private Isolate getSharedIsolate() { private void sharedIsolateShutdown() { Isolate isolate = getSharedIsolate(); - CompilerIsolateThread context = (CompilerIsolateThread) Isolates.attachCurrentThread(isolate); - compilerIsolateThreadShutdown(context); - Isolates.detachThread(context); + if (isolate.isNonNull()) { + CompilerIsolateThread context = (CompilerIsolateThread) Isolates.attachCurrentThread(isolate); + compilerIsolateThreadShutdown(context); + Isolates.detachThread(context); + } } @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) From d463a8f62d8f74f4dcf8b13f50ee32e728230e7a Mon Sep 17 00:00:00 2001 From: jovanstevanovic Date: Mon, 26 Feb 2024 12:55:47 +0100 Subject: [PATCH 07/77] Backport: Register the virtual thread group unconditionally. --- .../oracle/svm/core/jfr/JfrThreadRepository.java | 5 +++++ .../thread/JavaLangThreadGroupSubstitutions.java | 3 ++- .../svm/core/thread/Target_java_lang_Thread.java | 7 ++++--- .../ThreadGroupConstantPoolParser.java | 15 +++++++++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadRepository.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadRepository.java index 89f61a338fcc..fa8b9ffc7ff0 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadRepository.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadRepository.java @@ -39,6 +39,7 @@ import com.oracle.svm.core.thread.JavaLangThreadGroupSubstitutions; import com.oracle.svm.core.thread.JavaThreads; import com.oracle.svm.core.thread.PlatformThreads; +import com.oracle.svm.core.thread.Target_java_lang_Thread; import com.oracle.svm.core.thread.VMOperation; import com.oracle.svm.core.thread.VMThreads; @@ -79,6 +80,10 @@ public void registerRunningThreads() { assert VMOperation.isInProgressAtSafepoint(); assert SubstrateJVM.get().isRecording(); + /* Register the virtual thread group unconditionally. */ + long virtualThreadGroupId = registerThreadGroup0(Target_java_lang_Thread.virtualThreadGroup()); + assert virtualThreadGroupId == VIRTUAL_THREAD_GROUP_ID; + for (IsolateThread isolateThread = VMThreads.firstThread(); isolateThread.isNonNull(); isolateThread = VMThreads.nextThread(isolateThread)) { /* * IsolateThreads without a Java thread just started executing and will register diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaLangThreadGroupSubstitutions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaLangThreadGroupSubstitutions.java index 5ae8ac905bab..33b6dcfdf07a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaLangThreadGroupSubstitutions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaLangThreadGroupSubstitutions.java @@ -93,7 +93,8 @@ class ThreadGroupIdAccessor { @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) static long getId(Target_java_lang_ThreadGroup that) { if (that.injectedId == 0) { - that.injectedId = nextID.getAndIncrement(); + Target_java_lang_ThreadGroup virtualThreadGroup = SubstrateUtil.cast(Target_java_lang_Thread.virtualThreadGroup(), Target_java_lang_ThreadGroup.class); + that.injectedId = that == virtualThreadGroup ? JfrThreadRepository.VIRTUAL_THREAD_GROUP_ID : nextID.getAndIncrement(); } return that.injectedId; } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java index 0bc51646f8b3..99e605db3d52 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java @@ -31,8 +31,6 @@ import java.util.Map; import java.util.Objects; -import jdk.graal.compiler.api.directives.GraalDirectives; -import jdk.graal.compiler.replacements.ReplacementsUtil; import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.impl.InternalPlatform; @@ -53,6 +51,9 @@ import com.oracle.svm.core.monitor.MonitorSupport; import com.oracle.svm.core.util.VMError; +import jdk.graal.compiler.api.directives.GraalDirectives; +import jdk.graal.compiler.replacements.ReplacementsUtil; + @TargetClass(Thread.class) @SuppressWarnings({"unused"}) public final class Target_java_lang_Thread { @@ -176,7 +177,7 @@ public long getId() { @AnnotateOriginal @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - static native ThreadGroup virtualThreadGroup(); + public static native ThreadGroup virtualThreadGroup(); @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) @AnnotateOriginal diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/ThreadGroupConstantPoolParser.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/ThreadGroupConstantPoolParser.java index c7a593dbced8..29ac09f5ff36 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/ThreadGroupConstantPoolParser.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/ThreadGroupConstantPoolParser.java @@ -28,23 +28,30 @@ import java.io.IOException; +import org.junit.Assert; + +import com.oracle.svm.core.jfr.JfrThreadRepository; import com.oracle.svm.core.jfr.JfrType; import com.oracle.svm.test.jfr.utils.JfrFileParser; import com.oracle.svm.test.jfr.utils.RecordingInput; public class ThreadGroupConstantPoolParser extends AbstractRepositoryParser { public ThreadGroupConstantPoolParser(JfrFileParser parser) { - /* 0 is the null thread group, 1 is the virtual thread group. */ - super(parser, 0L, 1L); + /* 0 is the null thread group. */ + super(parser, 0L); } @Override public void parse(RecordingInput input) throws IOException { int numberOfThreadGroups = input.readInt(); for (int i = 0; i < numberOfThreadGroups; i++) { - addFoundId(input.readLong()); // ThreadGroupId. + long threadGroupId = input.readLong(); + addFoundId(threadGroupId); // ThreadGroupId. addExpectedId(JfrType.ThreadGroup, input.readLong()); // ParentThreadGroupId. - input.readUTF(); // ThreadGroupName. + String threadGroupName = input.readUTF(); // ThreadGroupName. + + /* For virtual threads, a fixed thread group id is reserved. */ + Assert.assertTrue(threadGroupId != JfrThreadRepository.VIRTUAL_THREAD_GROUP_ID || threadGroupName.equals("VirtualThreads")); } } } From 4dc78b3c4a72183bd5ca24a6ab0d800e8648be24 Mon Sep 17 00:00:00 2001 From: Yudi Zheng Date: Fri, 22 Dec 2023 10:39:26 +0100 Subject: [PATCH 08/77] Deprecate ZeroExtendNode.inputAlwaysPositive. --- .../amd64/AMD64HotSpotAddressLowering.java | 4 ++-- .../graal/compiler/nodes/calc/SignExtendNode.java | 2 +- .../graal/compiler/nodes/calc/ZeroExtendNode.java | 15 ++++----------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java index e8fe9643dff3..50a4c581f525 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java @@ -187,14 +187,14 @@ private static ValueNode signExtend(ValueNode input, LoopEx loop) { if (init >= 0 && extremum >= 0) { long shortestTrip = (extremum - init) / stride + 1; if (countedLoopInfo.constantMaxTripCount().equals(shortestTrip)) { - return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true)); + return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, false)); } } } if (countedLoopInfo.getLimitCheckedIV() == inductionVariable && inductionVariable.direction() == InductionVariable.Direction.Up && (countedLoopInfo.getOverFlowGuard() != null || countedLoopInfo.counterNeverOverflows())) { - return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true)); + return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, false)); } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/SignExtendNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/SignExtendNode.java index 10563f91855c..24cd5019d899 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/SignExtendNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/SignExtendNode.java @@ -124,7 +124,7 @@ private static ValueNode canonical(SignExtendNode self, ValueNode forValue, int if ((inputStamp.mayBeSet() & (1L << (inputBits - 1))) == 0L) { // 0xxx -(sign-extend)-> 0000 0xxx // ==> 0xxx -(zero-extend)-> 0000 0xxx - return ZeroExtendNode.create(forValue, inputBits, resultBits, view, true); + return ZeroExtendNode.create(forValue, inputBits, resultBits, view, false); } } if (forValue instanceof NarrowNode) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/ZeroExtendNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/ZeroExtendNode.java index ee26d641b7f7..ecf3d8ba81e1 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/ZeroExtendNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/ZeroExtendNode.java @@ -35,6 +35,7 @@ import jdk.graal.compiler.core.common.type.PrimitiveStamp; import jdk.graal.compiler.core.common.type.Stamp; import jdk.graal.compiler.debug.Assertions; +import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.NodeClass; import jdk.graal.compiler.lir.gen.ArithmeticLIRGeneratorTool; import jdk.graal.compiler.nodeinfo.NodeInfo; @@ -67,14 +68,15 @@ public ZeroExtendNode(ValueNode input, int resultBits) { public ZeroExtendNode(ValueNode input, int inputBits, int resultBits, boolean inputAlwaysPositive) { super(TYPE, BinaryArithmeticNode.getArithmeticOpTable(input).getZeroExtend(), inputBits, resultBits, input); this.inputAlwaysPositive = inputAlwaysPositive; + GraalError.guarantee(!inputAlwaysPositive, "ZeroExtendNode.inputAlwaysPositive is deprecated."); } public static ValueNode create(ValueNode input, int resultBits, NodeView view) { - return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view, inputAlwaysPositive(input)); + return create(input, PrimitiveStamp.getBits(input.stamp(view)), resultBits, view, false); } public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view) { - return create(input, inputBits, resultBits, view, inputAlwaysPositive(input)); + return create(input, inputBits, resultBits, view, false); } public static ValueNode create(ValueNode input, int inputBits, int resultBits, NodeView view, boolean alwaysPositive) { @@ -86,15 +88,6 @@ public static ValueNode create(ValueNode input, int inputBits, int resultBits, N return canonical(null, input, inputBits, resultBits, view, alwaysPositive); } - private static boolean inputAlwaysPositive(ValueNode v) { - Stamp s = v.stamp(NodeView.DEFAULT); - if (s instanceof IntegerStamp) { - return ((IntegerStamp) s).isPositive(); - } else { - return false; - } - } - @Override protected IntegerConvertOp getOp(ArithmeticOpTable table) { return table.getZeroExtend(); From 9ea43a67e8f5a567ccb6cd85f60f4affb76e6dec Mon Sep 17 00:00:00 2001 From: jovanstevanovic Date: Fri, 8 Mar 2024 12:02:47 +0100 Subject: [PATCH 09/77] Update -g to include all information for profiling. Fix the problem with objcopy strip command. --- .../com/oracle/svm/core/SubstrateOptions.java | 8 +++- .../NativeImageDebugInfoStripFeature.java | 39 ++++++++++++------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index 4cb22f602036..eca966dd8903 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -744,8 +744,12 @@ public static int codeAlignment() { public static final HostedOptionKey GenerateDebugInfo = new HostedOptionKey<>(0, SubstrateOptions::validateGenerateDebugInfo) { @Override protected void onValueUpdate(EconomicMap, Object> values, Integer oldValue, Integer newValue) { - if (OS.WINDOWS.isCurrent()) { - /* Keep symbols on Windows. The symbol table is part of the pdb-file. */ + if (!OS.DARWIN.isCurrent()) { + /* + * Keep the symbol table, as it may be used by debugging or profiling tools (e.g., + * perf). On Windows, the symbol table is included in the pdb-file, while on Linux, + * it is part of the .debug file. + */ DeleteLocalSymbols.update(values, newValue == 0); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoStripFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoStripFeature.java index 3d454d147768..982aad62ef8e 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoStripFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoStripFeature.java @@ -28,10 +28,8 @@ import java.nio.file.Files; import java.nio.file.Path; -import jdk.graal.compiler.debug.DebugContext; -import jdk.graal.compiler.debug.DebugContext.Builder; -import jdk.graal.compiler.debug.Indent; -import jdk.graal.compiler.printer.GraalDebugHandlersFactory; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.impl.InternalPlatform; import com.oracle.graal.pointsto.util.GraalAccess; import com.oracle.objectfile.ObjectFile; @@ -47,12 +45,18 @@ import com.oracle.svm.hosted.c.util.FileUtils; import com.oracle.svm.util.LogUtils; +import jdk.graal.compiler.core.common.SuppressFBWarnings; +import jdk.graal.compiler.debug.DebugContext; +import jdk.graal.compiler.debug.DebugContext.Builder; +import jdk.graal.compiler.debug.Indent; +import jdk.graal.compiler.printer.GraalDebugHandlersFactory; + @AutomaticallyRegisteredFeature public class NativeImageDebugInfoStripFeature implements InternalFeature { @Override public boolean isInConfiguration(IsInConfigurationAccess access) { - return SubstrateOptions.useDebugInfoGeneration() && SubstrateOptions.StripDebugInfo.getValue(); + return SubstrateOptions.StripDebugInfo.getValue(); } @SuppressWarnings("try") @@ -77,13 +81,17 @@ public void afterImageWrite(AfterImageWriteAccess access) { } } + @SuppressFBWarnings(value = "", justification = "FB reports null pointer dereferencing although it is not possible in this case.") private static void stripLinux(AfterImageWriteAccessImpl accessImpl) { String objcopyExe = "objcopy"; String debugExtension = ".debug"; Path imagePath = accessImpl.getImagePath(); + if (imagePath == null) { + assert !Platform.includedIn(InternalPlatform.NATIVE_ONLY.class); + return; + } + Path imageName = imagePath.getFileName(); - Path outputDirectory = imagePath.getParent(); - String debugInfoName = imageName + debugExtension; boolean objcopyAvailable = false; try { objcopyAvailable = FileUtils.executeCommand(objcopyExe, "--version") == 0; @@ -94,16 +102,21 @@ private static void stripLinux(AfterImageWriteAccessImpl accessImpl) { } if (!objcopyAvailable) { - LogUtils.warning("%s not available. Skipping generation of separate debuginfo file %s, debuginfo will remain embedded in the executable.", objcopyExe, debugInfoName); + LogUtils.warning("%s not available. The debuginfo will remain embedded in the executable.", objcopyExe); } else { try { + Path outputDirectory = imagePath.getParent(); String imageFilePath = outputDirectory.resolve(imageName).toString(); - Path debugInfoFilePath = outputDirectory.resolve(debugInfoName); - FileUtils.executeCommand(objcopyExe, "--only-keep-debug", imageFilePath, debugInfoFilePath.toString()); - BuildArtifacts.singleton().add(ArtifactType.DEBUG_INFO, debugInfoFilePath); + if (SubstrateOptions.useDebugInfoGeneration()) { + /* Generate a separate debug file before stripping the executable. */ + String debugInfoName = imageName + debugExtension; + Path debugInfoFilePath = outputDirectory.resolve(debugInfoName); + FileUtils.executeCommand(objcopyExe, "--only-keep-debug", imageFilePath, debugInfoFilePath.toString()); + BuildArtifacts.singleton().add(ArtifactType.DEBUG_INFO, debugInfoFilePath); + FileUtils.executeCommand(objcopyExe, "--add-gnu-debuglink=" + debugInfoFilePath, imageFilePath); + } Path exportedSymbolsPath = createKeepSymbolsListFile(accessImpl); FileUtils.executeCommand(objcopyExe, "--strip-all", "--keep-symbols=" + exportedSymbolsPath, imageFilePath); - FileUtils.executeCommand(objcopyExe, "--add-gnu-debuglink=" + debugInfoFilePath, imageFilePath); } catch (IOException e) { throw UserError.abort("Generation of separate debuginfo file failed", e); } catch (InterruptedException e) { @@ -114,7 +127,7 @@ private static void stripLinux(AfterImageWriteAccessImpl accessImpl) { private static Path createKeepSymbolsListFile(AfterImageWriteAccessImpl accessImpl) throws IOException { Path exportedSymbolsPath = accessImpl.getTempDirectory().resolve("keep-symbols.list").toAbsolutePath(); - Files.write(exportedSymbolsPath, accessImpl.getImageSymbols(false)); + Files.write(exportedSymbolsPath, accessImpl.getImageSymbols(true)); return exportedSymbolsPath; } } From 62c2046aeebe2d3923ba2bb6a49f97d68f2eb05e Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Mon, 26 Feb 2024 13:19:21 +0100 Subject: [PATCH 10/77] [GR-52324] Add InsertGuardFencesPhase into runtime compilation phases. (cherry picked from commit 3c8e0e0d39f6ce5b0cd1458a8ac78d6897f82848) --- .../compiler/phases/common/InsertGuardFencesPhase.java | 7 ++++++- .../src/com/oracle/svm/truffle/TruffleFeature.java | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/InsertGuardFencesPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/InsertGuardFencesPhase.java index 0983eaf4ddd1..01175be01f6a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/InsertGuardFencesPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/InsertGuardFencesPhase.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Optional; +import jdk.graal.compiler.core.common.SpectrePHTMitigations; import jdk.graal.compiler.core.common.type.IntegerStamp; import jdk.graal.compiler.debug.Assertions; import jdk.graal.compiler.debug.DebugContext; @@ -68,6 +69,10 @@ public Optional notApplicableTo(GraphState graphState) { @Override protected void run(StructuredGraph graph) { + SpectrePHTMitigations mitigations = SpectrePHTBarriers.getValue(graph.getOptions()); + if (mitigations == SpectrePHTMitigations.None || mitigations == SpectrePHTMitigations.AllTargets) { + return; + } ControlFlowGraph cfg = ControlFlowGraph.newBuilder(graph).connectBlocks(true).computeFrequency(true).build(); for (AbstractBeginNode beginNode : graph.getNodes(AbstractBeginNode.TYPE)) { if (hasPotentialUnsafeAccess(cfg, beginNode)) { @@ -76,7 +81,7 @@ protected void run(StructuredGraph graph) { continue; } if (hasGuardUsages(beginNode)) { - if (SpectrePHTBarriers.getValue(graph.getOptions()) == NonDeoptGuardTargets) { + if (mitigations == NonDeoptGuardTargets) { if (isDeoptGuard(beginNode)) { graph.getDebug().log(DebugContext.VERBOSE_LEVEL, "Skipping deoptimizing guard speculation fence at %s", beginNode); continue; diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java index b5dfccdbe3c2..3ee589aee718 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java @@ -100,6 +100,7 @@ import java.util.function.ToLongFunction; import java.util.function.UnaryOperator; +import jdk.graal.compiler.phases.common.InsertGuardFencesPhase; import org.graalvm.collections.Pair; import org.graalvm.nativeimage.AnnotationAccess; import org.graalvm.nativeimage.ImageSingletons; @@ -972,6 +973,15 @@ public void registerGraalPhases(Providers providers, SnippetReflectionProvider s if (hosted && HostInliningPhase.Options.TruffleHostInlining.getValue(HostedOptionValues.singleton()) && suites.getHighTier() instanceof HighTier) { suites.getHighTier().prependPhase(new SubstrateHostInliningPhase(CanonicalizerPhase.create())); } + /* + * On HotSpot, the InsertGuardFencesPhase is inserted into the mid-tier depending on the + * runtime option SpectrePHTBarriers. However, TruffleFeature registers phases during + * image-build time. Therefore, for Truffle compilations, we need to register the phase + * eagerly because the SpectrePHTBarriers options is set only at image-execution time. + */ + if (!hosted && suites.getMidTier().findPhase(InsertGuardFencesPhase.class, true) == null) { + suites.getMidTier().appendPhase(new InsertGuardFencesPhase()); + } } } From 28e94b8938e7ec1f71f06e2f4b7f4bf528192669 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 29 Feb 2024 08:56:12 +0100 Subject: [PATCH 11/77] [GR-52616] Limit Log.exception() output. --- .../src/com/oracle/svm/core/log/RealLog.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/log/RealLog.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/log/RealLog.java index 4c490be18d0b..ed6a932ef2cd 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/log/RealLog.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/log/RealLog.java @@ -648,7 +648,12 @@ public Log exception(Throwable t, int maxFrames) { } Throwable cur = t; - do { + int maxCauses = 25; + for (int i = 0; i < maxCauses && cur != null; i++) { + if (i > 0) { + newline().string("Caused by: "); + } + /* * We do not want to call getMessage(), since it can be overridden by subclasses of * Throwable. So we access the raw detailMessage directly from the field in Throwable. @@ -668,23 +673,20 @@ public Log exception(Throwable t, int maxFrames) { } else { StackTraceElement[] stackTrace = JDKUtils.getRawStackTrace(cur); if (stackTrace != null) { - int i; - for (i = 0; i < stackTrace.length && i < maxFrames; i++) { - StackTraceElement element = stackTrace[i]; + int j; + for (j = 0; j < stackTrace.length && j < maxFrames; j++) { + StackTraceElement element = stackTrace[j]; if (element != null) { printJavaFrame(element.getClassName(), element.getMethodName(), element.getFileName(), element.getLineNumber()); } } - int remaining = stackTrace.length - i; + int remaining = stackTrace.length - j; printRemainingFramesCount(remaining); } } cur = JDKUtils.getRawCause(cur); - if (cur != null) { - newline().string("Caused by: "); - } - } while (cur != null); + } return this; } From c61f5d90025d1d746d0daacd0313d39272c99cca Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 29 Feb 2024 08:58:05 +0100 Subject: [PATCH 12/77] [GR-52616] Prevent register writes from floating. --- .../svm/core/SubstrateSegfaultHandler.java | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateSegfaultHandler.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateSegfaultHandler.java index e84606ddf7ae..65e2f398b116 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateSegfaultHandler.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateSegfaultHandler.java @@ -170,42 +170,52 @@ protected static boolean tryEnterIsolate(RegisterDumper.Context context) { } /* Try to determine the isolate via the thread register. */ - if (SubstrateOptions.MultiThreaded.getValue()) { - /* - * Set the thread register to null so that we don't execute this code more than once if - * we trigger a recursive segfault. - */ - WriteCurrentVMThreadNode.writeCurrentVMThread(WordFactory.nullPointer()); - - IsolateThread isolateThread = (IsolateThread) RegisterDumper.singleton().getThreadPointer(context); - if (isolateThread.isNonNull()) { - isolate = VMThreads.IsolateTL.get(isolateThread); - if (isValid(isolate)) { - if (SubstrateOptions.SpawnIsolates.getValue()) { - CEntryPointSnippets.setHeapBase(isolate); - } - - WriteCurrentVMThreadNode.writeCurrentVMThread(isolateThread); - return true; - } - } + if (SubstrateOptions.MultiThreaded.getValue() && tryEnterIsolateViaThreadRegister(context)) { + return true; } /* Try to determine the isolate via the heap base register. */ - if (SubstrateOptions.SpawnIsolates.getValue()) { - /* - * Set the heap base register to null so that we don't execute this code more than once - * if we trigger a recursive segfault. - */ - CEntryPointSnippets.setHeapBase(WordFactory.nullPointer()); + return SubstrateOptions.SpawnIsolates.getValue() && tryEnterIsolateViaHeapBaseRegister(context); + } + + @Uninterruptible(reason = "Thread state not set up yet.") + @NeverInline("Prevent register writes from floating") + private static boolean tryEnterIsolateViaThreadRegister(RegisterDumper.Context context) { + /* + * Try to determine the isolate via the thread register. Set the thread register to null so + * that we don't execute this code more than once if we trigger a recursive segfault. + */ + WriteCurrentVMThreadNode.writeCurrentVMThread(WordFactory.nullPointer()); - isolate = (Isolate) RegisterDumper.singleton().getHeapBase(context); + IsolateThread isolateThread = (IsolateThread) RegisterDumper.singleton().getThreadPointer(context); + if (isolateThread.isNonNull()) { + Isolate isolate = VMThreads.IsolateTL.get(isolateThread); if (isValid(isolate)) { - int error = CEntryPointSnippets.enterAttachFromCrashHandler(isolate); - return error == CEntryPointErrors.NO_ERROR; + if (SubstrateOptions.SpawnIsolates.getValue()) { + CEntryPointSnippets.setHeapBase(isolate); + } + + WriteCurrentVMThreadNode.writeCurrentVMThread(isolateThread); + return true; } } + return false; + } + @Uninterruptible(reason = "Thread state not set up yet.") + @NeverInline("Prevent register writes from floating") + private static boolean tryEnterIsolateViaHeapBaseRegister(RegisterDumper.Context context) { + /* + * Set the heap base register to null so that we don't execute this code more than once if + * we trigger a recursive segfault. + */ + CEntryPointSnippets.setHeapBase(WordFactory.nullPointer()); + + Isolate isolate = (Isolate) RegisterDumper.singleton().getHeapBase(context); + if (isValid(isolate)) { + int error = CEntryPointSnippets.enterAttachFromCrashHandler(isolate); + return error == CEntryPointErrors.NO_ERROR; + } return false; } From de0832def4ec054ea1ea90a1a7cb79a1bb7dca09 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 29 Feb 2024 09:48:32 +0100 Subject: [PATCH 13/77] [GR-52434] ExitOnOutOfMemoryError must wait until HeapDumpOnOutOfMemoryError finishes. --- .../oracle/svm/core/heap/OutOfMemoryUtil.java | 21 ++++++++++++------- .../core/heap/dump/HeapDumpSupportImpl.java | 20 ++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/OutOfMemoryUtil.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/OutOfMemoryUtil.java index 5ab7d43ebeb5..07e3b5a6ade5 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/OutOfMemoryUtil.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/OutOfMemoryUtil.java @@ -31,8 +31,8 @@ import com.oracle.svm.core.headers.LibC; import com.oracle.svm.core.heap.dump.HeapDumping; import com.oracle.svm.core.jdk.JDKUtils; -import com.oracle.svm.core.jdk.UninterruptibleUtils.AtomicBoolean; import com.oracle.svm.core.log.Log; +import com.oracle.svm.core.stack.StackOverflowCheck; import com.oracle.svm.core.util.VMError; /** @@ -43,11 +43,6 @@ public class OutOfMemoryUtil { private static final OutOfMemoryError OUT_OF_MEMORY_ERROR = new OutOfMemoryError("Garbage-collected heap size exceeded. Consider increasing the maximum Java heap size, for example with '-Xmx'."); - /** - * Guard to ensure heap dump on OOME is performed at most once. - */ - private static final AtomicBoolean HEAP_DUMPED = new AtomicBoolean(false); - @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Can't allocate when out of memory.") public static OutOfMemoryError heapSizeExceeded() { return reportOutOfMemoryError(OUT_OF_MEMORY_ERROR); @@ -56,7 +51,18 @@ public static OutOfMemoryError heapSizeExceeded() { @Uninterruptible(reason = "Not uninterruptible but it doesn't matter for the callers.", calleeMustBe = false) @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Can't allocate while out of memory.") public static OutOfMemoryError reportOutOfMemoryError(OutOfMemoryError error) { - if (VMInspectionOptions.hasHeapDumpSupport() && SubstrateOptions.HeapDumpOnOutOfMemoryError.getValue() && HEAP_DUMPED.compareAndSet(false, true)) { + StackOverflowCheck.singleton().makeYellowZoneAvailable(); + try { + reportOutOfMemoryError0(error); + } finally { + StackOverflowCheck.singleton().protectYellowZone(); + } + throw error; + } + + @Uninterruptible(reason = "Not uninterruptible but it doesn't matter for the callers.", calleeMustBe = false) + private static void reportOutOfMemoryError0(OutOfMemoryError error) { + if (VMInspectionOptions.hasHeapDumpSupport() && SubstrateOptions.HeapDumpOnOutOfMemoryError.getValue()) { HeapDumping.singleton().dumpHeapOnOutOfMemoryError(); } @@ -68,6 +74,5 @@ public static OutOfMemoryError reportOutOfMemoryError(OutOfMemoryError error) { VMError.shouldNotReachHere("ExitOnOutOfMemoryError can only be used if the LibC support is present."); } } - throw error; } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpSupportImpl.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpSupportImpl.java index 95cffbb587bd..c8f8f20f13b6 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpSupportImpl.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/dump/HeapDumpSupportImpl.java @@ -46,6 +46,7 @@ import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.heap.RestrictHeapAccess; import com.oracle.svm.core.heap.VMOperationInfos; +import com.oracle.svm.core.locks.VMMutex; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.os.RawFileOperationSupport; import com.oracle.svm.core.os.RawFileOperationSupport.FileCreationMode; @@ -58,8 +59,10 @@ public class HeapDumpSupportImpl extends HeapDumping { private final HeapDumpWriter writer; private final HeapDumpOperation heapDumpOperation; + private final VMMutex outOfMemoryHeapDumpMutex = new VMMutex("outOfMemoryHeapDump"); private CCharPointer outOfMemoryHeapDumpPath; + private boolean outOfMemoryHeapDumpAttempted; @Platforms(Platform.HOSTED_ONLY.class) public HeapDumpSupportImpl(HeapDumpMetadata metadata) { @@ -84,6 +87,23 @@ public void teardownDumpHeapOnOutOfMemoryError() { @Override @RestrictHeapAccess(access = NO_ALLOCATION, reason = "OutOfMemoryError heap dumping must not allocate.") public void dumpHeapOnOutOfMemoryError() { + /* + * Try exactly once to create an out-of-memory heap dump. If another thread triggers an + * OutOfMemoryError while heap dumping is in progress, it needs to wait until heap dumping + * finishes. + */ + outOfMemoryHeapDumpMutex.lock(); + try { + if (!outOfMemoryHeapDumpAttempted) { + dumpHeapOnOutOfMemoryError0(); + outOfMemoryHeapDumpAttempted = true; + } + } finally { + outOfMemoryHeapDumpMutex.unlock(); + } + } + + private void dumpHeapOnOutOfMemoryError0() { CCharPointer path = outOfMemoryHeapDumpPath; if (path.isNull()) { Log.log().string("OutOfMemoryError heap dumping failed because the heap dump file path could not be allocated.").newline(); From baa88a811a0edc9c654da51381cb0a5bc3948e4c Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 29 Feb 2024 10:05:12 +0100 Subject: [PATCH 14/77] [GR-52613] Improve a code installation error message. --- .../code/AbstractRuntimeCodeInstaller.java | 6 ++--- .../svm/core/code/RuntimeCodeInfoAccess.java | 22 ++++++++++++----- .../os/AbstractCommittedMemoryProvider.java | 22 ----------------- .../svm/core/os/CommittedMemoryProvider.java | 24 ++----------------- .../IsolatedRuntimeCodeInstaller.java | 8 +++---- 5 files changed, 24 insertions(+), 58 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java index 5824017ccd0e..54c96796f0cc 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java @@ -47,13 +47,11 @@ protected Pointer allocateCodeMemory(long size) { } protected void makeCodeMemoryExecutableReadOnly(Pointer start, UnsignedWord size) { - int result = RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size); - VMError.guarantee(result == 0, "Failed to make code memory read only."); + RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size); } protected void makeCodeMemoryExecutableWritable(Pointer start, UnsignedWord size) { - int result = RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size); - VMError.guarantee(result == 0, "Failed to make code memory writable."); + RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size); } protected static void doInstallPrepared(SharedMethod method, CodeInfo codeInfo, SubstrateInstalledCode installedCode) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeInfoAccess.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeInfoAccess.java index 334672f9fc6a..5adc54ea46f9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeInfoAccess.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeInfoAccess.java @@ -24,8 +24,6 @@ */ package com.oracle.svm.core.code; -import java.util.EnumSet; - import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.UnmanagedMemory; import org.graalvm.nativeimage.c.function.CodePointer; @@ -46,6 +44,7 @@ import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.heap.ObjectReferenceVisitor; import com.oracle.svm.core.os.CommittedMemoryProvider; +import com.oracle.svm.core.os.VirtualMemoryProvider; import com.oracle.svm.core.util.DuplicatedInNativeCode; import com.oracle.svm.core.util.VMError; @@ -235,12 +234,23 @@ private static void releaseCodeMemory(CodePointer codeStart, UnsignedWord codeSi CommittedMemoryProvider.get().freeExecutableMemory(codeStart, codeSize, WordFactory.unsigned(SubstrateOptions.codeAlignment())); } - public static int makeCodeMemoryExecutableReadOnly(CodePointer codeStart, UnsignedWord codeSize) { - return CommittedMemoryProvider.get().protect(codeStart, codeSize, EnumSet.of(CommittedMemoryProvider.Access.READ, CommittedMemoryProvider.Access.EXECUTE)); + public static void makeCodeMemoryExecutableReadOnly(CodePointer codeStart, UnsignedWord codeSize) { + protectCodeMemory(codeStart, codeSize, VirtualMemoryProvider.Access.READ | VirtualMemoryProvider.Access.EXECUTE); + } + + public static void makeCodeMemoryExecutableWritable(CodePointer start, UnsignedWord size) { + VMError.guarantee(RuntimeCodeCache.Options.WriteableCodeCache.getValue(), "memory must not be writable and executable at the same time unless we have a writable code cache"); + protectCodeMemory(start, size, VirtualMemoryProvider.Access.READ | VirtualMemoryProvider.Access.WRITE | VirtualMemoryProvider.Access.EXECUTE); } - public static int makeCodeMemoryExecutableWritable(CodePointer start, UnsignedWord size) { - return CommittedMemoryProvider.get().protect(start, size, EnumSet.of(CommittedMemoryProvider.Access.READ, CommittedMemoryProvider.Access.WRITE, CommittedMemoryProvider.Access.EXECUTE)); + private static void protectCodeMemory(CodePointer codeStart, UnsignedWord codeSize, int permissions) { + int result = VirtualMemoryProvider.get().protect(codeStart, codeSize, permissions); + if (result != 0) { + throw VMError.shouldNotReachHere("Failed to modify protection of code memory. This may be caused by " + + "a. a too restrictive OS-limit of allowed memory mappings (see vm.max_map_count on Linux), " + + "b. a too strict security policy if you are running on Security-Enhanced Linux (SELinux), or " + + "c. a Native Image internal error."); + } } @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java index 55c4add3af9e..9c2539d9a77c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java @@ -30,8 +30,6 @@ import static com.oracle.svm.core.Isolates.IMAGE_HEAP_WRITABLE_END; import static org.graalvm.word.WordFactory.nullPointer; -import java.util.EnumSet; - import jdk.graal.compiler.api.replacements.Fold; import org.graalvm.word.Pointer; import org.graalvm.word.PointerBase; @@ -41,11 +39,9 @@ import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.c.function.CEntryPointErrors; -import com.oracle.svm.core.code.RuntimeCodeCache; import com.oracle.svm.core.config.ConfigurationValues; import com.oracle.svm.core.heap.Heap; import com.oracle.svm.core.util.UnsignedUtils; -import com.oracle.svm.core.util.VMError; public abstract class AbstractCommittedMemoryProvider implements CommittedMemoryProvider { @Fold @@ -85,24 +81,6 @@ protected static int protectSingleIsolateImageHeap() { return CEntryPointErrors.NO_ERROR; } - @Override - public int protect(PointerBase start, UnsignedWord nbytes, EnumSet accessFlags) { - int vmAccessBits = VirtualMemoryProvider.Access.NONE; - if (accessFlags.contains(CommittedMemoryProvider.Access.READ)) { - vmAccessBits |= VirtualMemoryProvider.Access.READ; - } - if (accessFlags.contains(CommittedMemoryProvider.Access.WRITE)) { - vmAccessBits |= VirtualMemoryProvider.Access.WRITE; - } - if (accessFlags.contains(CommittedMemoryProvider.Access.EXECUTE)) { - if ((vmAccessBits & VirtualMemoryProvider.Access.WRITE) != 0 && !RuntimeCodeCache.Options.WriteableCodeCache.getValue()) { - throw VMError.shouldNotReachHere("memory should never be writable and executable at the same time"); - } - vmAccessBits |= VirtualMemoryProvider.Access.EXECUTE; - } - return VirtualMemoryProvider.get().protect(start, nbytes, vmAccessBits); - } - @Override @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public Pointer allocateAlignedChunk(UnsignedWord nbytes, UnsignedWord alignment) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java index c1111a02654c..47074c1c7f4a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java @@ -24,9 +24,6 @@ */ package com.oracle.svm.core.os; -import java.util.EnumSet; - -import jdk.graal.compiler.api.replacements.Fold; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.c.type.WordPointer; import org.graalvm.word.Pointer; @@ -37,6 +34,8 @@ import com.oracle.svm.core.c.function.CEntryPointCreateIsolateParameters; import com.oracle.svm.core.heap.Heap; +import jdk.graal.compiler.api.replacements.Fold; + /** * A provider of ranges of committed memory, which is virtual memory that is backed by physical * memory or swap space. @@ -117,23 +116,4 @@ default void beforeGarbageCollection() { */ default void afterGarbageCollection() { } - - enum Access { - READ, - WRITE, - EXECUTE - } - - /** - * Change access permissions for a block of committed memory that was allocated with one of the - * allocation methods. - * - * @param start The start of the address range to be protected, which must be a multiple of the - * {@linkplain #getGranularity() granularity}. - * @param nbytes The size in bytes of the address range to be protected, which will be rounded - * up to a multiple of the {@linkplain #getGranularity() granularity}. - * @param access The modes in which the memory is permitted to be accessed, see {@link Access}. - * @return 0 when successful, or a non-zero implementation-specific error code. - */ - int protect(PointerBase start, UnsignedWord nbytes, EnumSet access); } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedRuntimeCodeInstaller.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedRuntimeCodeInstaller.java index 9e1bb36ba2f5..1236c845e2f7 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedRuntimeCodeInstaller.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedRuntimeCodeInstaller.java @@ -162,8 +162,8 @@ protected void makeCodeMemoryExecutableReadOnly(Pointer start, UnsignedWord size } @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) - private static int makeCodeMemoryExecutableReadOnly0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) { - return RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size); + private static void makeCodeMemoryExecutableReadOnly0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) { + RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size); } @Override @@ -172,7 +172,7 @@ protected void makeCodeMemoryExecutableWritable(Pointer start, UnsignedWord size } @CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished) - private static int makeCodeMemoryExecutableWritable0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) { - return RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size); + private static void makeCodeMemoryExecutableWritable0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) { + RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size); } } From bdb47df9e657b97959731d6b376e9f67e0ec93d0 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Mon, 19 Feb 2024 12:14:32 +0100 Subject: [PATCH 15/77] loop fragment: ensure we are not killing control flow when we have nodes in head/tail counted position that are actually empty themselves (skipable) (cherry picked from commit 89ce6d15dcfccbd1eccfa3ced3cd1fd3a7a554d4) --- .../compiler/nodes/loop/LoopFragmentInside.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopFragmentInside.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopFragmentInside.java index bb9873a838a3..bd4714117fca 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopFragmentInside.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/LoopFragmentInside.java @@ -291,6 +291,8 @@ protected CompareNode placeNewSegmentAndCleanup(LoopEx loop, EconomicMap Date: Wed, 13 Mar 2024 17:14:17 +0000 Subject: [PATCH 16/77] GR-50768 : new dev cycle GraalVM 24.0.1 --- compiler/mx.compiler/suite.py | 4 ++-- espresso/mx.espresso/suite.py | 4 ++-- regex/mx.regex/suite.py | 4 ++-- sdk/mx.sdk/suite.py | 4 ++-- substratevm/mx.substratevm/suite.py | 4 ++-- tools/mx.tools/suite.py | 4 ++-- truffle/external_repos/simplelanguage/pom.xml | 2 +- truffle/external_repos/simpletool/pom.xml | 2 +- truffle/mx.truffle/suite.py | 4 ++-- vm/mx.vm/suite.py | 10 +++++----- wasm/mx.wasm/suite.py | 2 +- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index f4adb1f98377..37da791f9c40 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -4,8 +4,8 @@ "sourceinprojectwhitelist" : [], "groupId" : "org.graalvm.compiler", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "url" : "http://www.graalvm.org/", "developer" : { "name" : "GraalVM Development", diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index 92bbe879a0ef..9cc5e3dff92d 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -24,8 +24,8 @@ suite = { "mxversion": "6.44.0", "name": "espresso", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "groupId" : "org.graalvm.espresso", "url" : "https://www.graalvm.org/reference-manual/java-on-truffle/", "developer" : { diff --git a/regex/mx.regex/suite.py b/regex/mx.regex/suite.py index 14c8744d5dc5..bf90debb6b3a 100644 --- a/regex/mx.regex/suite.py +++ b/regex/mx.regex/suite.py @@ -43,8 +43,8 @@ "name" : "regex", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "groupId" : "org.graalvm.regex", "url" : "http://www.graalvm.org/", "developer" : { diff --git a/sdk/mx.sdk/suite.py b/sdk/mx.sdk/suite.py index cac3b6038762..889d26fa0979 100644 --- a/sdk/mx.sdk/suite.py +++ b/sdk/mx.sdk/suite.py @@ -41,8 +41,8 @@ suite = { "mxversion": "6.53.2", "name" : "sdk", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "sourceinprojectwhitelist" : [], "url" : "https://github.com/oracle/graal", "groupId" : "org.graalvm.sdk", diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 610f0cf4b63c..04ba4e31500e 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -2,8 +2,8 @@ suite = { "mxversion": "6.27.1", "name": "substratevm", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "url" : "https://github.com/oracle/graal/tree/master/substratevm", "groupId" : "org.graalvm.nativeimage", diff --git a/tools/mx.tools/suite.py b/tools/mx.tools/suite.py index ba78f0cadf50..4e0eb547d9ce 100644 --- a/tools/mx.tools/suite.py +++ b/tools/mx.tools/suite.py @@ -26,8 +26,8 @@ "defaultLicense" : "GPLv2-CPE", "groupId" : "org.graalvm.tools", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "url" : "http://openjdk.java.net/projects/graal", "developer" : { "name" : "GraalVM Development", diff --git a/truffle/external_repos/simplelanguage/pom.xml b/truffle/external_repos/simplelanguage/pom.xml index e33816257dc6..1797a1e618b3 100644 --- a/truffle/external_repos/simplelanguage/pom.xml +++ b/truffle/external_repos/simplelanguage/pom.xml @@ -47,7 +47,7 @@ UTF-8 jdt_apt - 24.0.0-dev + 24.0.1-dev 17 17 org.graalvm.sl.launcher/com.oracle.truffle.sl.launcher.SLMain diff --git a/truffle/external_repos/simpletool/pom.xml b/truffle/external_repos/simpletool/pom.xml index afde0af17a67..f4be91c70b3e 100644 --- a/truffle/external_repos/simpletool/pom.xml +++ b/truffle/external_repos/simpletool/pom.xml @@ -48,7 +48,7 @@ ${graalvm.version} simpletool - 24.0.0-dev + 24.0.1-dev UTF-8 17 17 diff --git a/truffle/mx.truffle/suite.py b/truffle/mx.truffle/suite.py index 8c7bbae03b0b..a0d0b277da91 100644 --- a/truffle/mx.truffle/suite.py +++ b/truffle/mx.truffle/suite.py @@ -41,8 +41,8 @@ suite = { "mxversion": "7.0.3", "name" : "truffle", - "version" : "24.0.0", - "release" : True, + "version" : "24.0.1", + "release" : False, "groupId" : "org.graalvm.truffle", "sourceinprojectwhitelist" : [], "url" : "http://openjdk.java.net/projects/graal", diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 8153ed9a9aae..046328eab34d 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -1,8 +1,8 @@ suite = { "name": "vm", - "version" : "24.0.0", + "version" : "24.0.1", "mxversion": "6.41.0", - "release" : True, + "release" : False, "groupId" : "org.graalvm", "url" : "http://www.graalvm.org/", @@ -33,7 +33,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "eac51cf01b8b0fb1fa8ea4dc4ff7834bebab89f3", + "version": "f2e7ec76a9b09262a636fcd3072dd22f89a9a0e6", "urls" : [ {"url" : "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] @@ -42,7 +42,7 @@ "name": "graal-js", "subdir": True, "dynamic": True, - "version": "eac51cf01b8b0fb1fa8ea4dc4ff7834bebab89f3", + "version": "f2e7ec76a9b09262a636fcd3072dd22f89a9a0e6", "urls": [ {"url": "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] @@ -65,7 +65,7 @@ }, { "name": "graalpython", - "version": "dd84460f5042bde971ed6df37565f171c853360c", + "version": "23e9e152541f731edf5878c7489a8a6fcbc5bcf4", "dynamic": True, "urls": [ {"url": "https://github.com/graalvm/graalpython.git", "kind": "git"}, diff --git a/wasm/mx.wasm/suite.py b/wasm/mx.wasm/suite.py index 8f59c3649b79..f6995454eda4 100644 --- a/wasm/mx.wasm/suite.py +++ b/wasm/mx.wasm/suite.py @@ -42,7 +42,7 @@ "mxversion": "6.41.0", "name" : "wasm", "groupId" : "org.graalvm.wasm", - "version" : "24.0.0", + "version" : "24.0.1", "versionConflictResolution" : "latest", "url" : "http://graalvm.org/", "developer" : { From d653ec9ee18d6b811bcacc2a0c380297019a2ee4 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Wed, 13 Mar 2024 23:22:12 +0000 Subject: [PATCH 17/77] fix no module named _sqlite3 : update graalpython revision --- vm/mx.vm/suite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 046328eab34d..829c20443a82 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -65,7 +65,7 @@ }, { "name": "graalpython", - "version": "23e9e152541f731edf5878c7489a8a6fcbc5bcf4", + "version": "2ff2ae7428da4a209340248cc672deea5f173ef4", "dynamic": True, "urls": [ {"url": "https://github.com/graalvm/graalpython.git", "kind": "git"}, From 97d950f78a7e25d90dd3a383cb45981f54ac550a Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Mon, 29 Jan 2024 17:03:51 +0100 Subject: [PATCH 18/77] update LockingMode constants --- .../compiler/hotspot/GraalHotSpotVMConfig.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java index f9c78435d7c8..04e88585e01c 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java @@ -129,9 +129,9 @@ private HotSpotGraalRuntime.HotSpotGC getSelectedGC() throws GraalError { // of the mark word. public final int lockingMode = getFlag("LockingMode", Integer.class); - public final int lockingModeMonitor = getConstant("LockingMode::LM_MONITOR", Integer.class, 0, JDK >= 22 && JDK_BUILD >= 18); - public final int lockingModeStack = getConstant("LockingMode::LM_LEGACY", Integer.class, 1, JDK >= 22 && JDK_BUILD >= 18); - public final int lockingModeLightweight = getConstant("LockingMode::LM_LIGHTWEIGHT", Integer.class, 2, JDK >= 22 && JDK_BUILD >= 18); + public final int lockingModeMonitor = getConstant("LockingMode::LM_MONITOR", Integer.class, 0, JDK >= 22); + public final int lockingModeStack = getConstant("LockingMode::LM_LEGACY", Integer.class, 1, JDK >= 22); + public final int lockingModeLightweight = getConstant("LockingMode::LM_LIGHTWEIGHT", Integer.class, 2, JDK >= 22); public final boolean foldStableValues = getFlag("FoldStableValues", Boolean.class); public final int maxVectorSize = getFlag("MaxVectorSize", Integer.class); @@ -270,7 +270,7 @@ public final int arrayOopDescLengthOffset() { public final int threadIsInVTMSTransitionOffset = getFieldOffset("JavaThread::_is_in_VTMS_transition", Integer.class, "bool"); public final int threadIsInTmpVTMSTransitionOffset = getFieldOffset("JavaThread::_is_in_tmp_VTMS_transition", Integer.class, "bool"); - public final int threadIsDisableSuspendOffset = getFieldOffset("JavaThread::_is_disable_suspend", Integer.class, "bool", -1, JDK >= 22 && JDK_BUILD >= 31); + public final int threadIsDisableSuspendOffset = getFieldOffset("JavaThread::_is_disable_suspend", Integer.class, "bool", -1, JDK >= 22); public final int javaLangThreadJFREpochOffset = getFieldValue("java_lang_Thread::_jfr_epoch_offset", Integer.class, "int"); public final int javaLangThreadTIDOffset = getFieldValue("java_lang_Thread::_tid_offset", Integer.class, "int"); @@ -351,7 +351,7 @@ public int threadLastJavaFpOffset() { public final int objectMonitorEntryList = getFieldOffset("ObjectMonitor::_EntryList", Integer.class, "ObjectWaiter*"); public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, "JavaThread*"); - public final long objectMonitorAnonymousOwner = getConstant("ObjectMonitor::ANONYMOUS_OWNER", Long.class, 1L, JDK >= 22 && JDK_BUILD >= 18); + public final long objectMonitorAnonymousOwner = getConstant("ObjectMonitor::ANONYMOUS_OWNER", Long.class, 1L, JDK >= 22); public final int markWordNoHashInPlace = getConstant("markWord::no_hash_in_place", Integer.class); public final int markWordNoLockInPlace = getConstant("markWord::no_lock_in_place", Integer.class); @@ -599,9 +599,9 @@ private long getZGCAddressField(String name) { // Tracking of the number of monitors held by the current thread. This is used by loom but in // JDK 20 was enabled by default to ensure it was correctly implemented. public final int threadHeldMonitorCountOffset = getFieldOffset("JavaThread::_held_monitor_count", Integer.class, JDK >= 22 ? "intx" : "int64_t"); - public final int threadLockStackOffset = getFieldOffset("JavaThread::_lock_stack", Integer.class, "LockStack", -1, JDK >= 22 && JDK_BUILD >= 18); - public final int lockStackTopOffset = getFieldOffset("LockStack::_top", Integer.class, "uint32_t", -1, JDK >= 22 && JDK_BUILD >= 18); - public final int lockStackEndOffset = getConstant("LockStack::_end_offset", Integer.class, -1, JDK >= 22 && JDK_BUILD >= 18); + public final int threadLockStackOffset = getFieldOffset("JavaThread::_lock_stack", Integer.class, "LockStack", -1, JDK >= 22); + public final int lockStackTopOffset = getFieldOffset("LockStack::_top", Integer.class, "uint32_t", -1, JDK >= 22); + public final int lockStackEndOffset = getConstant("LockStack::_end_offset", Integer.class, -1, JDK >= 22); public final long throwAndPostJvmtiExceptionAddress = getAddress("JVMCIRuntime::throw_and_post_jvmti_exception"); public final long throwKlassExternalNameExceptionAddress = getAddress("JVMCIRuntime::throw_klass_external_name_exception"); From 219c6998f244ed032d3e8cb3008df0a535a62fa3 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Mon, 29 Jan 2024 10:44:36 +0100 Subject: [PATCH 19/77] tmp test jdk-22.0.1+2 --- ci/common.jsonnet | 9 --------- compiler/mx.compiler/mx_compiler.py | 6 +----- .../jdk/graal/compiler/hotspot/JVMCIVersionCheck.java | 2 +- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/ci/common.jsonnet b/ci/common.jsonnet index 308e51e13d5a..c0794d82065f 100644 --- a/ci/common.jsonnet +++ b/ci/common.jsonnet @@ -64,15 +64,6 @@ local common_json = import "../common.json"; # We do not want to expose galahad-jdk assert std.assertEqual([x for x in std.objectFields(common_json.jdks) if x != "galahad-jdk"], std.objectFields(jdks_data)), # Verify oraclejdk-latest and labsjdk-ee-latest versions match - assert - local _labsjdk = common_json.jdks["labsjdk-ee-latest"]; - local _oraclejdk = common_json.jdks["oraclejdk-latest"]; - local _ov = "ee-%s+%s" % [_oraclejdk.version, _oraclejdk.build_id]; - local _lv = _labsjdk.version; - # Skip the check if we are not using a labsjdk. This can happen on JDK integration branches. - local no_labsjdk = _labsjdk.name != "labsjdk"; - assert no_labsjdk || std.startsWith(_lv, _ov) : "update oraclejdk-latest to match labsjdk-ee-latest: %s+%s vs %s" % [_oraclejdk.version, _oraclejdk.build_id, _labsjdk.version]; - true, # The raw jdk data, the same as common_json.jdks + { jdk_version:: } jdks_data: jdks_data, diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index ecc94e4a73dc..eaecb3054299 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -1292,11 +1292,7 @@ def add_serviceprovider(service, provider, version): def __closing__(self): _record_last_updated_jar(self.dist, self.arc.path) - if self.dist.name == 'GRAAL': - # Check if we're using the same JVMCI JDK as the CI system does. - # This only done when building the GRAAL distribution so as to - # not be too intrusive. - _check_latest_jvmci_version() + mx.add_argument('--vmprefix', action='store', dest='vm_prefix', help='prefix for running the VM (e.g. "gdb --args")', metavar='') mx.add_argument('--gdb', action='store_const', const='gdb --args', dest='vm_prefix', help='alias for --vmprefix "gdb --args"') diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java index 29668cdc19f8..fbcac7c73844 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java @@ -54,7 +54,7 @@ public final class JVMCIVersionCheck { private static final Map> JVMCI_MIN_VERSIONS = Map.of( "21", Map.of(DEFAULT_VENDOR_ENTRY, new Version(23, 1, 26)), "22", Map.of( - "Oracle Corporation", new Version("22+36", 2), + "Oracle Corporation", new Version("22.0.1+6", 1), DEFAULT_VENDOR_ENTRY, new Version("22+36", 2))); private static final int NA = 0; /** From d84520023bc1278ee811142ca7dc72df24e38780 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Thu, 14 Mar 2024 00:16:42 +0000 Subject: [PATCH 20/77] update labsjdk to jdk-22.0.1+8 --- common.json | 6 +++--- .../src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common.json b/common.json index b14bcd2c0741..6aad5d3e1831 100644 --- a/common.json +++ b/common.json @@ -48,9 +48,9 @@ "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22+36-jvmci-b02", "platformspecific": true }, "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22+36-jvmci-b02-debug", "platformspecific": true }, "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22+36-jvmci-b02-sulong", "platformspecific": true }, - "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-22+36-jvmci-b02", "platformspecific": true }, - "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-22+36-jvmci-b02-debug", "platformspecific": true }, - "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-22+36-jvmci-b02-sulong", "platformspecific": true } + "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e", "platformspecific": true }, + "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e-debug", "platformspecific": true }, + "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e-sulong", "platformspecific": true } }, "eclipse": { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java index fbcac7c73844..a8577a5a6bd8 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java @@ -54,7 +54,7 @@ public final class JVMCIVersionCheck { private static final Map> JVMCI_MIN_VERSIONS = Map.of( "21", Map.of(DEFAULT_VENDOR_ENTRY, new Version(23, 1, 26)), "22", Map.of( - "Oracle Corporation", new Version("22.0.1+6", 1), + "Oracle Corporation", new Version("22.0.1+8", 1), DEFAULT_VENDOR_ENTRY, new Version("22+36", 2))); private static final int NA = 0; /** From 9566c61d0cdb8b769bd0f66dbc71eb8fd644609b Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Thu, 14 Mar 2024 14:47:00 +0000 Subject: [PATCH 21/77] re-enable JVMCI check --- compiler/mx.compiler/mx_compiler.py | 6 +++++- .../src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/mx.compiler/mx_compiler.py b/compiler/mx.compiler/mx_compiler.py index eaecb3054299..ecc94e4a73dc 100644 --- a/compiler/mx.compiler/mx_compiler.py +++ b/compiler/mx.compiler/mx_compiler.py @@ -1292,7 +1292,11 @@ def add_serviceprovider(service, provider, version): def __closing__(self): _record_last_updated_jar(self.dist, self.arc.path) - + if self.dist.name == 'GRAAL': + # Check if we're using the same JVMCI JDK as the CI system does. + # This only done when building the GRAAL distribution so as to + # not be too intrusive. + _check_latest_jvmci_version() mx.add_argument('--vmprefix', action='store', dest='vm_prefix', help='prefix for running the VM (e.g. "gdb --args")', metavar='') mx.add_argument('--gdb', action='store_const', const='gdb --args', dest='vm_prefix', help='alias for --vmprefix "gdb --args"') diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java index a8577a5a6bd8..767c699c24ba 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java @@ -55,7 +55,7 @@ public final class JVMCIVersionCheck { "21", Map.of(DEFAULT_VENDOR_ENTRY, new Version(23, 1, 26)), "22", Map.of( "Oracle Corporation", new Version("22.0.1+8", 1), - DEFAULT_VENDOR_ENTRY, new Version("22+36", 2))); + DEFAULT_VENDOR_ENTRY, new Version("22.0.1+8", 1))); private static final int NA = 0; /** * Minimum Java release supported by Graal. From 456309750a21ab3f93bd42f729490d1b8648ed71 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Thu, 14 Mar 2024 14:48:03 +0000 Subject: [PATCH 22/77] update labsjdk 22 CE to 22.0.1+8 --- common.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common.json b/common.json index 6aad5d3e1831..d3f87ae1d67b 100644 --- a/common.json +++ b/common.json @@ -45,9 +45,9 @@ "labsjdk-ee-21-llvm": {"name": "labsjdk", "version": "ee-21.0.1+11-jvmci-23.1-b26-sulong", "platformspecific": true }, "oraclejdk-latest": {"name": "jpg-jdk", "version": "22", "build_id": "36", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, - "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22+36-jvmci-b02", "platformspecific": true }, - "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22+36-jvmci-b02-debug", "platformspecific": true }, - "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22+36-jvmci-b02-sulong", "platformspecific": true }, + "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-20240314142246-e61b751b8d", "platformspecific": true }, + "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-20240314142246-e61b751b8d-debug", "platformspecific": true }, + "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-20240314142246-e61b751b8d-sulong", "platformspecific": true }, "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e", "platformspecific": true }, "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e-debug", "platformspecific": true }, "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e-sulong", "platformspecific": true } From 65eba9e9aa8ffe237b1a76582c56acad281b4f8d Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Fri, 23 Feb 2024 12:39:24 +0100 Subject: [PATCH 23/77] add conditional elimination 17 test: contributed by Andreas Woess (cherry picked from commit 0b609cb3ef77647a8087825836cd7bda4df246c2) --- .../test/ConditionalEliminationTest17.java | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java new file mode 100644 index 000000000000..435825d9b08e --- /dev/null +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.graal.compiler.core.test; + +import java.util.EnumSet; + +import org.junit.Test; + +import jdk.graal.compiler.api.directives.GraalDirectives; +import jdk.vm.ci.meta.DeoptimizationReason; + +/** + * GR-52269 + */ +public class ConditionalEliminationTest17 extends ConditionalEliminationTestBase { + + static final class A { + } + + static final class B { + int value = 1337; + + int value() { + return value; + } + } + + private static boolean equals(byte[] a, byte[] b) { + if (a == b) { + return true; + } else if (a.length != b.length) { + return false; + } else { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + } + + private static final Object X = new Object(); + private static final Object Y = new Object(); + + public static int test1Snippet(byte[][] haystack, byte[] needle, Object[] otherValues) { + Object someValue = otherValues[0]; + Object anotherValue1 = otherValues[1]; + Object anotherValue2 = otherValues[2]; + if (haystack.length != 0) { + for (int i = 0; i < haystack.length; i++) { + byte[] hay = haystack[i]; + if (equals(hay, needle)) { + int result = 42; + if (anotherValue1 == X) { + if (anotherValue2 == Y) { + result++; + GraalDirectives.controlFlowAnchor(); + } + GraalDirectives.controlFlowAnchor(); + } + if (someValue.getClass() != A.class) { + GraalDirectives.deoptimizeAndInvalidate(); + } + GraalDirectives.controlFlowAnchor(); + return result; + } + } + } + return ((B) someValue).value(); + } + + @Test + public void test1() { + Object[] args = {new byte[][]{"foo".getBytes(), "bar".getBytes()}, "neither".getBytes(), new Object[]{new B(), X, Y}}; + test(getInitialOptions(), EnumSet.allOf(DeoptimizationReason.class), "test1Snippet", args); + } + + public static int test2Snippet(byte[][] haystack, byte[] needle, Object[] otherValues) { + Object someValue = otherValues[0]; + Object anotherValue1 = otherValues[1]; + Object anotherValue2 = otherValues[2]; + if (haystack.length != 0) { + for (int i = 0; i < haystack.length; i++) { + byte[] hay = haystack[i]; + if (equals(hay, needle)) { + int result = 42; + if (anotherValue1 == X) { + if (anotherValue2 == Y) { + result++; + GraalDirectives.controlFlowAnchor(); + } + GraalDirectives.controlFlowAnchor(); + } + if (someValue == null || someValue.getClass() != A.class) { + GraalDirectives.deoptimizeAndInvalidate(); + } + GraalDirectives.controlFlowAnchor(); + return result; + } + } + } + return ((B) someValue).value(); + } + + @Test + public void test2() { + Object[] args = {new byte[][]{"foo".getBytes(), "bar".getBytes()}, "bad".getBytes(), new Object[]{new B(), X, Y}}; + test(getInitialOptions(), EnumSet.allOf(DeoptimizationReason.class), "test2Snippet", args); + } + + private static boolean simpleEquals(byte[] a, byte[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + + } + + // simplified and reduced version of test1Snippet + public static int test3Snippet(byte[][] haystack, byte[] needle, Object[] otherValues) { + Object someValue = otherValues[0]; + Object anotherValue1 = otherValues[1]; + // if (haystack.length != 0) { + for (int i = 0; i < haystack.length; i++) { + byte[] hay = haystack[i]; + if (simpleEquals(hay, needle)) { + int result = 42; + if (anotherValue1 == X) { + GraalDirectives.controlFlowAnchor(); + } + if (someValue.getClass() != A.class) { + GraalDirectives.deoptimizeAndInvalidate(); + } + return result; + } + } + // } + return ((B) someValue).value(); + } + + @Test + public void test3() { + Object[] args = {new byte[][]{"foo".getBytes(), "bar".getBytes()}, "neither".getBytes(), new Object[]{new B(), X, Y}}; + test(getInitialOptions(), EnumSet.allOf(DeoptimizationReason.class), "test3Snippet", args); + } + +} From 2ec5d14633906107dbc15e98bac54273d8e9834b Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Fri, 23 Feb 2024 16:24:16 +0100 Subject: [PATCH 24/77] cfg: add logging decorator for cfg traversal (cherry picked from commit 7ace7941f06d1e87d1bd95c3522524eebc55470a) --- .../compiler/nodes/cfg/ControlFlowGraph.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/cfg/ControlFlowGraph.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/cfg/ControlFlowGraph.java index 501a69a71c19..7838929ff282 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/cfg/ControlFlowGraph.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/cfg/ControlFlowGraph.java @@ -44,6 +44,7 @@ import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.debug.MemUseTrackerKey; +import jdk.graal.compiler.debug.TTY; import jdk.graal.compiler.graph.Node; import jdk.graal.compiler.graph.NodeMap; import jdk.graal.compiler.graph.iterators.NodeIterable; @@ -219,6 +220,44 @@ public void updateCachedLocalLoopFrequency(LoopBeginNode lb, Function { + private final ControlFlowGraph.RecursiveVisitor visitor; + private String indent = ""; + + public LoggingCFGDecorator(ControlFlowGraph.RecursiveVisitor visitor, ControlFlowGraph cfg) { + this.visitor = visitor; + TTY.printf("DomTree for %s%n", cfg.graph); + printDomTree(cfg.getStartBlock(), ""); + } + + private static void printDomTree(HIRBlock cur, String indent) { + TTY.printf("%s%s [dom %s, post dom %s]%n", indent, cur, cur.getDominator(), cur.getPostdominator()); + HIRBlock dominated = cur.getFirstDominated(); + while (dominated != null) { + printDomTree(dominated, indent + "\t"); + dominated = dominated.getDominatedSibling(); + } + } + + @Override + public HIRBlock enter(HIRBlock b) { + TTY.printf("%sEnter block %s for %s%n", indent, b, visitor); + indent += "\t"; + return visitor.enter(b); + } + + @Override + public void exit(HIRBlock b, HIRBlock value) { + indent = indent.substring(0, indent.length() - 1); + TTY.printf("%sExit block %s with value %s for %s%n", indent, b, value, visitor); + visitor.exit(b, value); + } + } + @SuppressWarnings("unchecked") public void visitDominatorTreeDefault(RecursiveVisitor visitor) { From 44ca3f803556b0f00e6f41d2172999685a3eb5d4 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Fri, 23 Feb 2024 16:25:32 +0100 Subject: [PATCH 25/77] simplify test further (cherry picked from commit ea811e7f1386b82fdff0d0c74f527c935552dd3c) --- .../test/ConditionalEliminationTest17.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java index 435825d9b08e..93a6eee4629d 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java @@ -29,6 +29,8 @@ import org.junit.Test; import jdk.graal.compiler.api.directives.GraalDirectives; +import jdk.graal.compiler.core.common.GraalOptions; +import jdk.graal.compiler.options.OptionValues; import jdk.vm.ci.meta.DeoptimizationReason; /** @@ -131,24 +133,24 @@ public void test2() { test(getInitialOptions(), EnumSet.allOf(DeoptimizationReason.class), "test2Snippet", args); } - private static boolean simpleEquals(byte[] a, byte[] b) { + // simplified and reduced version of equals (semantics of this method is not relevant, only IR + // shape) + private static boolean simpleEquals(byte[][] a) { for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - return false; + if (GraalDirectives.sideEffect(i) == 123) { + return true; } } - return true; + return false; } - // simplified and reduced version of test1Snippet - public static int test3Snippet(byte[][] haystack, byte[] needle, Object[] otherValues) { - Object someValue = otherValues[0]; - Object anotherValue1 = otherValues[1]; - // if (haystack.length != 0) { + // simplified and reduced version of test1Snippet (semantics of this method is not relevant, + // only IR shape) + @SuppressWarnings("unused") + public static int test3Snippet(byte[][] haystack, byte[] needle, Object someValue, Object anotherValue1) { for (int i = 0; i < haystack.length; i++) { - byte[] hay = haystack[i]; - if (simpleEquals(hay, needle)) { + if (simpleEquals(haystack)) { int result = 42; if (anotherValue1 == X) { GraalDirectives.controlFlowAnchor(); @@ -159,14 +161,14 @@ public static int test3Snippet(byte[][] haystack, byte[] needle, Object[] otherV return result; } } - // } - return ((B) someValue).value(); + return 0; } @Test public void test3() { - Object[] args = {new byte[][]{"foo".getBytes(), "bar".getBytes()}, "neither".getBytes(), new Object[]{new B(), X, Y}}; - test(getInitialOptions(), EnumSet.allOf(DeoptimizationReason.class), "test3Snippet", args); + Object[] args = {new byte[][]{"foo".getBytes(), "bar".getBytes()}, "neither".getBytes(), X, Y}; + OptionValues opt = new OptionValues(getInitialOptions(), GraalOptions.OptFloatingReads, false); + test(opt, EnumSet.allOf(DeoptimizationReason.class), "test3Snippet", args); } } From 7ac1e3f7eb9fc5979ac1a26c810a43946eaf09d8 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Fri, 23 Feb 2024 16:26:27 +0100 Subject: [PATCH 26/77] MoveGuardsUpwards: fix conceptual problem with not respecting the dom tree traversal necessary for the algorithm design to work (cherry picked from commit 84ceba648afbd5d8e9942ab367b2c06c58fa2822) --- .../common/ConditionalEliminationPhase.java | 176 ++++++++++-------- 1 file changed, 101 insertions(+), 75 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java index 447a7f0c23fd..b54f0f3878b9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java @@ -99,8 +99,8 @@ import jdk.graal.compiler.options.Option; import jdk.graal.compiler.options.OptionKey; import jdk.graal.compiler.options.OptionType; +import jdk.graal.compiler.phases.common.util.LoopUtility; import jdk.graal.compiler.phases.schedule.SchedulePhase; - import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.SpeculationLog.Speculation; import jdk.vm.ci.meta.TriState; @@ -178,8 +178,13 @@ protected void run(StructuredGraph graph, CoreProviders context) { if (fullSchedule) { cfg = ControlFlowGraph.newBuilder(graph).backendBlocks(true).connectBlocks(true).computeFrequency(true).computeLoops(true).computeDominators(true).computePostdominators( true).build(); + graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "Conditional elimination after computing CFG"); if (moveGuards && Options.MoveGuardsUpwards.getValue(graph.getOptions())) { - cfg.visitDominatorTree(new MoveGuardsUpwards(), graph.isBeforeStage(StageFlag.VALUE_PROXY_REMOVAL)); + /** + * See comment in {@link MoveGuardsUpwards#enter}. + */ + final boolean deferLoopExits = false; + cfg.visitDominatorTree(new MoveGuardsUpwards(), deferLoopExits); } try (DebugContext.Scope scheduleScope = graph.getDebug().scope(SchedulePhase.class)) { SchedulePhase.run(graph, SchedulePhase.SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER, cfg, context, false); @@ -212,6 +217,11 @@ public static class MoveGuardsUpwards implements ControlFlowGraph.RecursiveVisit HIRBlock anchorBlock; + @Override + public String toString() { + return "MoveGuardsUpwards - anchorBlock=" + anchorBlock; + } + /** * Guards cannot be moved above CaptureStateBeginNodes in order to ensure deoptimizations * are always attached to valid FrameStates. @@ -225,6 +235,8 @@ private static boolean disallowUpwardGuardMovement(HIRBlock b) { public HIRBlock enter(HIRBlock b) { HIRBlock oldAnchorBlock = anchorBlock; /* + * REASONING: + * * The goal of this pass is to move guards upward while not introducing the guards on * new paths. At all points the anchorBlock must set so the following two invariants * hold: @@ -256,87 +268,101 @@ public HIRBlock enter(HIRBlock b) { anchorBlock = b; } - AbstractBeginNode beginNode = b.getBeginNode(); - if (beginNode instanceof AbstractMergeNode && anchorBlock != b) { - AbstractMergeNode mergeNode = (AbstractMergeNode) beginNode; - mergeNode.replaceAtUsages(anchorBlock.getBeginNode(), InputType.Anchor, InputType.Guard); - mergeNode.graph().getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, mergeNode.graph(), "After moving guard and anchored usages from %s to %s", mergeNode, anchorBlock.getBeginNode()); - assert mergeNode.anchored().isEmpty(); - } - - FixedNode endNode = b.getEndNode(); - if (endNode instanceof IfNode) { - IfNode node = (IfNode) endNode; - - // Check if we can move guards upwards. - AbstractBeginNode trueSuccessor = node.trueSuccessor(); - AbstractBeginNode falseSuccessor = node.falseSuccessor(); + final AbstractBeginNode beginNode = b.getBeginNode(); - EconomicMap trueGuards = EconomicMap.create(Equivalence.IDENTITY); - for (GuardNode guard : trueSuccessor.guards()) { - LogicNode condition = guard.getCondition(); - if (condition.hasMoreThanOneUsage()) { - trueGuards.put(condition, guard); - } + /** + * A note on loop exits and deferred loop exits in dominator tree traversal for + * MoveGuardsUpwards: We must not defer loop exits when we run the move guards upwards + * because a loop exit block is itself part of the dominator tree (normally as a + * dedicated block) and we cannot leave it out. All the logic explained above under + * "REASONING" is only correct if we visit all blocks in dominance order. Thus, when we + * move guards we must ensure we are safe proxy wise. + */ + final boolean canMoveGuardsTo = b.getCfg().graph.isAfterStage(StageFlag.VALUE_PROXY_REMOVAL) || LoopUtility.canUseWithoutProxy(b.getCfg(), anchorBlock.getBeginNode(), b.getBeginNode()); + + if (canMoveGuardsTo) { + if (anchorBlock != b) { + AbstractBeginNode abstractBegin = beginNode; + abstractBegin.replaceAtUsages(anchorBlock.getBeginNode(), InputType.Anchor, InputType.Guard); + abstractBegin.graph().getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, abstractBegin.graph(), "After moving guard and anchored usages from %s to %s", abstractBegin, + anchorBlock.getBeginNode()); + assert abstractBegin.anchored().isEmpty(); } - if (!trueGuards.isEmpty()) { - /* - * Special case loop exits: We must only ever move guards over loop exits if we - * move them over all loop exits (i.e. if a successor is a loop exit it must be - * the only loop exit or a loop has two exits and both are successors of the - * current if). Else we would risk moving a guard from after a particular exit - * into the loop (might be loop invariant) which can be too early resulting in - * the generated code deopting without the need to. - * - * Note: The code below is written with the possibility in mind that both - * successors are loop exits, even of potentially different loops. Thus, we need - * to ensure we see all possible loop exits involved for all loops. - */ - EconomicSet allLoopsAllExits = null; - if (trueSuccessor instanceof LoopExitNode successor) { - if (allLoopsAllExits == null) { - allLoopsAllExits = EconomicSet.create(); + FixedNode endNode = b.getEndNode(); + if (endNode instanceof IfNode) { + IfNode node = (IfNode) endNode; + + // Check if we can move guards upwards. + AbstractBeginNode trueSuccessor = node.trueSuccessor(); + AbstractBeginNode falseSuccessor = node.falseSuccessor(); + + EconomicMap trueGuards = EconomicMap.create(Equivalence.IDENTITY); + for (GuardNode guard : trueSuccessor.guards()) { + LogicNode condition = guard.getCondition(); + if (condition.hasMoreThanOneUsage()) { + trueGuards.put(condition, guard); } - allLoopsAllExits.addAll(successor.loopBegin().loopExits()); - allLoopsAllExits.remove(successor); } - if (falseSuccessor instanceof LoopExitNode successor) { - if (allLoopsAllExits == null) { - allLoopsAllExits = EconomicSet.create(); + if (!trueGuards.isEmpty()) { + /* + * Special case loop exits: We must only ever move guards over loop exits if + * we move them over all loop exits (i.e. if a successor is a loop exit it + * must be the only loop exit or a loop has two exits and both are + * successors of the current if). Else we would risk moving a guard from + * after a particular exit into the loop (might be loop invariant) which can + * be too early resulting in the generated code deopting without the need + * to. + * + * Note: The code below is written with the possibility in mind that both + * successors are loop exits, even of potentially different loops. Thus, we + * need to ensure we see all possible loop exits involved for all loops. + */ + EconomicSet allLoopsAllExits = null; + if (trueSuccessor instanceof LoopExitNode successor) { + if (allLoopsAllExits == null) { + allLoopsAllExits = EconomicSet.create(); + } + allLoopsAllExits.addAll(successor.loopBegin().loopExits()); + allLoopsAllExits.remove(successor); } - allLoopsAllExits.addAll(successor.loopBegin().loopExits()); - allLoopsAllExits.remove(successor); - } - if (allLoopsAllExits == null || allLoopsAllExits.isEmpty()) { - for (GuardNode falseGuard : falseSuccessor.guards().snapshot()) { - GuardNode trueGuard = trueGuards.get(falseGuard.getCondition()); - if (trueGuard != null && falseGuard.isNegated() == trueGuard.isNegated()) { - Speculation speculation = trueGuard.getSpeculation(); - if (speculation == null) { - speculation = falseGuard.getSpeculation(); - } else if (falseGuard.getSpeculation() != null && falseGuard.getSpeculation() != speculation) { - // Cannot optimize due to different speculations. - continue; - } - try (DebugCloseable closeable = falseGuard.withNodeSourcePosition()) { - StructuredGraph graph = falseGuard.graph(); - GuardNode newlyCreatedGuard = new GuardNode(falseGuard.getCondition(), anchorBlock.getBeginNode(), falseGuard.getReason(), falseGuard.getAction(), - falseGuard.isNegated(), speculation, - falseGuard.getNoDeoptSuccessorPosition()); - GuardNode newGuard = node.graph().unique(newlyCreatedGuard); - if (trueGuard.isAlive()) { - if (trueSuccessor instanceof LoopExitNode && beginNode.graph().isBeforeStage(StageFlag.VALUE_PROXY_REMOVAL)) { - trueGuard.replaceAndDelete(ProxyNode.forGuard(newGuard, (LoopExitNode) trueSuccessor)); + if (falseSuccessor instanceof LoopExitNode successor) { + if (allLoopsAllExits == null) { + allLoopsAllExits = EconomicSet.create(); + } + allLoopsAllExits.addAll(successor.loopBegin().loopExits()); + allLoopsAllExits.remove(successor); + } + if (allLoopsAllExits == null || allLoopsAllExits.isEmpty()) { + for (GuardNode falseGuard : falseSuccessor.guards().snapshot()) { + GuardNode trueGuard = trueGuards.get(falseGuard.getCondition()); + if (trueGuard != null && falseGuard.isNegated() == trueGuard.isNegated()) { + Speculation speculation = trueGuard.getSpeculation(); + if (speculation == null) { + speculation = falseGuard.getSpeculation(); + } else if (falseGuard.getSpeculation() != null && falseGuard.getSpeculation() != speculation) { + // Cannot optimize due to different speculations. + continue; + } + try (DebugCloseable closeable = falseGuard.withNodeSourcePosition()) { + StructuredGraph graph = falseGuard.graph(); + GuardNode newlyCreatedGuard = new GuardNode(falseGuard.getCondition(), anchorBlock.getBeginNode(), falseGuard.getReason(), falseGuard.getAction(), + falseGuard.isNegated(), speculation, + falseGuard.getNoDeoptSuccessorPosition()); + GuardNode newGuard = node.graph().unique(newlyCreatedGuard); + if (trueGuard.isAlive()) { + if (trueSuccessor instanceof LoopExitNode && beginNode.graph().isBeforeStage(StageFlag.VALUE_PROXY_REMOVAL)) { + trueGuard.replaceAndDelete(ProxyNode.forGuard(newGuard, (LoopExitNode) trueSuccessor)); + } else { + trueGuard.replaceAndDelete(newGuard); + } + } + if (falseSuccessor instanceof LoopExitNode && beginNode.graph().isBeforeStage(StageFlag.VALUE_PROXY_REMOVAL)) { + falseGuard.replaceAndDelete(ProxyNode.forGuard(newGuard, (LoopExitNode) falseSuccessor)); } else { - trueGuard.replaceAndDelete(newGuard); + falseGuard.replaceAndDelete(newGuard); } + graph.getOptimizationLog().report(ConditionalEliminationPhase.class, "GuardCombination", falseGuard); } - if (falseSuccessor instanceof LoopExitNode && beginNode.graph().isBeforeStage(StageFlag.VALUE_PROXY_REMOVAL)) { - falseGuard.replaceAndDelete(ProxyNode.forGuard(newGuard, (LoopExitNode) falseSuccessor)); - } else { - falseGuard.replaceAndDelete(newGuard); - } - graph.getOptimizationLog().report(ConditionalEliminationPhase.class, "GuardCombination", falseGuard); } } } From c347916f31e03a9a8a78e077ee7739a0d86c9f8d Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Fri, 23 Feb 2024 16:29:28 +0100 Subject: [PATCH 27/77] checkstyle fixes (cherry picked from commit 510bb4f90b5bbe53118a990fa6436104f67caa3e) --- .../graal/compiler/core/test/ConditionalEliminationTest17.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java index 93a6eee4629d..27bde36a85d4 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/ConditionalEliminationTest17.java @@ -33,9 +33,6 @@ import jdk.graal.compiler.options.OptionValues; import jdk.vm.ci.meta.DeoptimizationReason; -/** - * GR-52269 - */ public class ConditionalEliminationTest17 extends ConditionalEliminationTestBase { static final class A { From 9dff8435d24bf6e24002d330081fb718c7c43610 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Mon, 4 Mar 2024 13:48:43 +0100 Subject: [PATCH 28/77] address review comments (cherry picked from commit a436de067640d3754cc2a8d6e95f2ceb7878a945) --- .../phases/common/ConditionalEliminationPhase.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java index b54f0f3878b9..048d9907fc36 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/ConditionalEliminationPhase.java @@ -277,10 +277,14 @@ public HIRBlock enter(HIRBlock b) { * dedicated block) and we cannot leave it out. All the logic explained above under * "REASONING" is only correct if we visit all blocks in dominance order. Thus, when we * move guards we must ensure we are safe proxy wise. + * + * In order to do so we verify that the location of the anchor block can be used by the + * current block without the need of any proxies. */ - final boolean canMoveGuardsTo = b.getCfg().graph.isAfterStage(StageFlag.VALUE_PROXY_REMOVAL) || LoopUtility.canUseWithoutProxy(b.getCfg(), anchorBlock.getBeginNode(), b.getBeginNode()); + final boolean canMoveGuardsToAnchorBlock = b.getCfg().graph.isAfterStage(StageFlag.VALUE_PROXY_REMOVAL) || + LoopUtility.canUseWithoutProxy(b.getCfg(), anchorBlock.getBeginNode(), b.getBeginNode()); - if (canMoveGuardsTo) { + if (canMoveGuardsToAnchorBlock) { if (anchorBlock != b) { AbstractBeginNode abstractBegin = beginNode; abstractBegin.replaceAtUsages(anchorBlock.getBeginNode(), InputType.Anchor, InputType.Guard); From 5643ab6756decf14de8b6f34021b57c0c219e07c Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Fri, 1 Mar 2024 12:55:29 +0100 Subject: [PATCH 29/77] don't try to resolve method parameter types from debugger, parse the signature instead to calculate the correct argCount. (cherry picked from commit c96e56fccc191a27409206b4f910fadb012e1586) --- .../truffle/espresso/jdwp/api/MethodRef.java | 14 +-- .../truffle/espresso/jdwp/impl/JDWP.java | 104 ++++++++++++------ .../oracle/truffle/espresso/impl/Method.java | 10 +- 3 files changed, 81 insertions(+), 47 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java index 59d5df18eb1c..2f13fa9ea876 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java @@ -107,13 +107,6 @@ public interface MethodRef { */ byte[] getOriginalCode(); - /** - * Returns all declared parameter types of the method. - * - * @return an array of parameter types - */ - KlassRef[] getParameters(); - /** * @return the local variable table of the method */ @@ -232,4 +225,11 @@ public interface MethodRef { * @return true if the method has a variable table */ boolean hasVariableTable(); + + /** + * Determines if the method was compiled with a variable type table. + * + * @return true if the method has a variable table + */ + boolean hasVariabletypeTable(); } diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java index fe7480f26e34..828f711d1a65 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java @@ -28,6 +28,8 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; +import java.util.stream.IntStream; +import java.util.stream.Stream; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.espresso.jdwp.api.CallFrame; @@ -1480,23 +1482,7 @@ static CommandResult createReply(Packet packet, JDWPContext context) { return new CommandResult(reply); } - if (!method.hasVariableTable()) { - reply.errorCode(ErrorCodes.ABSENT_INFORMATION); - return new CommandResult(reply); - } - - KlassRef[] params = method.getParameters(); - int argCnt = 0; // the number of words in the frame used by the arguments - for (KlassRef klass : params) { - if (klass.isPrimitive()) { - byte tag = klass.getTagConstant(); - if (tag == TagConstants.DOUBLE || tag == TagConstants.LONG) { - argCnt += 2; - } else { - argCnt++; - } - } - } + int argCnt = getArgCount(method.getSignatureAsString()); LocalRef[] locals = method.getLocalVariableTable().getLocals(); reply.writeInt(argCnt); @@ -1583,24 +1569,8 @@ static CommandResult createReply(Packet packet, JDWPContext context) { if (method == null) { return new CommandResult(reply); } - - if (!method.hasVariableTable()) { - reply.errorCode(ErrorCodes.ABSENT_INFORMATION); - return new CommandResult(reply); - } - - KlassRef[] params = method.getParameters(); - int argCnt = 0; // the number of words in the frame used by the arguments - for (KlassRef klass : params) { - if (klass.isPrimitive()) { - byte tag = klass.getTagConstant(); - if (tag == TagConstants.DOUBLE || tag == TagConstants.LONG) { - argCnt += 2; - } else { - argCnt++; - } - } - } + // the number of words in the frame used by the arguments + int argCnt = getArgCount(method.getSignatureAsString()); LocalRef[] locals = method.getLocalVariableTable().getLocals(); LocalRef[] genericLocals = method.getLocalVariableTypeTable().getLocals(); @@ -3240,6 +3210,70 @@ private static int checkSyntheticFlag(int modBits) { return mod; } + private static int getArgCount(String signature) { + int startIndex = signature.indexOf('(') + 1; + int endIndex = signature.indexOf(')'); + String parameterSig = signature.substring(startIndex, endIndex); + int currentCount = 0; + int currentIndex = 0; + char[] charArray = parameterSig.toCharArray(); + while (currentIndex < charArray.length) { + switch (charArray[currentIndex]) { + case 'D': + case 'J': { + currentCount += 2; + currentIndex++; + break; + } + case 'B': + case 'C': + case 'F': + case 'I': + case 'S': + case 'Z': { + currentCount++; + currentIndex++; + break; + } + case 'L': + currentCount++; + currentIndex = parameterSig.indexOf(';', currentIndex) + 1; + break; + case 'T': + throw new RuntimeException("unexpected type variable"); + case '[': + currentCount++; + currentIndex += parseArrayType(parameterSig, charArray, currentIndex + 1); + break; + default: + throw new RuntimeException("should not reach here"); + } + } + return currentCount; + } + + private static int parseArrayType(String signature, char[] charArray, int currentIndex) { + switch (charArray[currentIndex]) { + case 'D': + case 'J': + case 'B': + case 'C': + case 'F': + case 'I': + case 'S': + case 'Z': + return 2; + case 'L': + return 2 + signature.indexOf(';', currentIndex) - currentIndex; + case 'T': + throw new RuntimeException("unexpected type variable"); + case '[': + return 1 + parseArrayType(signature, charArray, currentIndex + 1); + default: + throw new RuntimeException("should not reach here"); + } + } + private static KlassRef verifyRefType(long refTypeId, PacketStream reply, JDWPContext context) { KlassRef klass; try { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java index ad5c2980fd9b..9195bf48115b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java @@ -1418,11 +1418,6 @@ public byte[] getOriginalCode() { return getCodeAttribute().getOriginalCode(); } - @Override - public KlassRef[] getParameters() { - return getMethod().getParameters(); - } - @Override public LocalVariableTable getLocalVariableTable() { if (codeAttribute != null) { @@ -1444,6 +1439,11 @@ public boolean hasVariableTable() { return getLocalVariableTable() != LocalVariableTable.EMPTY_LVT; } + @Override + public boolean hasVariabletypeTable() { + return getLocalVariableTypeTable() != LocalVariableTable.EMPTY_LVTT; + } + @Override public LineNumberTableAttribute getLineNumberTable() { return getLineNumberTableAttribute(); From 2d82b9d99975fda6e48c72a60ba2837418e22475 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Fri, 1 Mar 2024 12:34:44 +0000 Subject: [PATCH 30/77] remove unsued imports (cherry picked from commit 0f06673776970dfe30c282700f3e1a6de63da73f) --- .../src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java index 828f711d1a65..01083bd660e6 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java @@ -28,8 +28,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; -import java.util.stream.IntStream; -import java.util.stream.Stream; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.espresso.jdwp.api.CallFrame; From 4ef9b60a0541dfdb2991b9f809636a4a28918f12 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Mon, 4 Mar 2024 07:28:33 +0100 Subject: [PATCH 31/77] remove unused methods (cherry picked from commit 8e3d4685a8486c1d1a045422c967f86b6fe2975a) --- .../truffle/espresso/jdwp/api/MethodRef.java | 14 -------------- .../com/oracle/truffle/espresso/impl/Method.java | 10 ---------- 2 files changed, 24 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java index 2f13fa9ea876..d37b6490d82a 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java @@ -218,18 +218,4 @@ public interface MethodRef { * @return last bci */ long getLastBCI(); - - /** - * Determines if the method was compiled with a variable table. - * - * @return true if the method has a variable table - */ - boolean hasVariableTable(); - - /** - * Determines if the method was compiled with a variable type table. - * - * @return true if the method has a variable table - */ - boolean hasVariabletypeTable(); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java index 9195bf48115b..e047d3213875 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java @@ -1434,16 +1434,6 @@ public LocalVariableTable getLocalVariableTypeTable() { return LocalVariableTable.EMPTY_LVTT; } - @Override - public boolean hasVariableTable() { - return getLocalVariableTable() != LocalVariableTable.EMPTY_LVT; - } - - @Override - public boolean hasVariabletypeTable() { - return getLocalVariableTypeTable() != LocalVariableTable.EMPTY_LVTT; - } - @Override public LineNumberTableAttribute getLineNumberTable() { return getLineNumberTableAttribute(); From 03c8608a775926104a572a2430210fdc0e5eddc7 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Fri, 15 Mar 2024 10:31:03 +0000 Subject: [PATCH 32/77] deploy snapshots --- common.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/common.json b/common.json index d3f87ae1d67b..1cc275111362 100644 --- a/common.json +++ b/common.json @@ -45,12 +45,12 @@ "labsjdk-ee-21-llvm": {"name": "labsjdk", "version": "ee-21.0.1+11-jvmci-23.1-b26-sulong", "platformspecific": true }, "oraclejdk-latest": {"name": "jpg-jdk", "version": "22", "build_id": "36", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, - "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-20240314142246-e61b751b8d", "platformspecific": true }, - "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-20240314142246-e61b751b8d-debug", "platformspecific": true }, - "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-20240314142246-e61b751b8d-sulong", "platformspecific": true }, - "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e", "platformspecific": true }, - "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e-debug", "platformspecific": true }, - "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-20240313063512-3dd40df11e+6772b5262e-sulong", "platformspecific": true } + "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01", "platformspecific": true }, + "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-sulong", "platformspecific": true }, + "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01", "platformspecific": true }, + "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-22.0.1+8-jvmci-b01-sulong", "platformspecific": true } }, "eclipse": { From 40247411c9c9d5f0c77e3dba800f66a744c1cb09 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 20 Feb 2024 11:45:09 +0100 Subject: [PATCH 33/77] new API method on RootNode that allows language root node implementations to provide the leaf node by using information stored within the frame. (cherry picked from commit ce910fc2ba81c4c8ee617686d396c1256d7b60a6) --- .../oracle/truffle/api/nodes/RootNode.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java index 59e1d5df93b6..ae2ac0aa616a 100644 --- a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java +++ b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java @@ -59,6 +59,7 @@ import com.oracle.truffle.api.TruffleStackTraceElement; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; @@ -591,6 +592,26 @@ protected FrameDescriptor getParentFrameDescriptor() { return null; } + /** + * If this root node supports obtaining precise location information from a frame instance, this + * method returns the leaf node corresponding to that location. The returned node must have this + * root node as a parent or be this root node itself. The passed frame instance must be the + * instance from which the reference to this root node was obtained. + *

+ * This is particularly useful in situations where the frame instance doesn't have an + * instrumentable call node. Hence, the precise location {@link SourceSection} in the associated + * frame cannot be obtained. Examples where a call node is not available include languages where + * e.g. substitutions or lazy class loading trigger calls into the guest language without being + * able to (easily) obtain the current caller node. + * + * @param frameInstance the frame instance + * @return The leaf node if supported. null otherwise. + * @since 24.1.0 + */ + public Node getLeafNodeByFrame(FrameInstance frameInstance) { + return null; + } + /** * Tests if two frames are the same. This method is mainly used by instruments in case of * yield of the execution and later resume. Frame comparison is used to match the From 4f50bc249d3ead797c0ae75cba2a0b27e9fe9d48 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 20 Feb 2024 11:47:26 +0100 Subject: [PATCH 34/77] pickup new API method to find a leaf (call node) node from a root node and frame instance (cherry picked from commit 8e91afd175fb5e156c35e9417f67ce23e03684e3) --- .../com/oracle/truffle/api/debug/DebuggerSession.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java index 3e14616522b9..d57407605b71 100644 --- a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java +++ b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java @@ -1137,11 +1137,14 @@ public Caller visitFrame(FrameInstance frameInstance) { while (callNode != null && !SourceSectionFilter.ANY.includes(callNode)) { callNode = callNode.getParent(); } - if (callNode == null) { + RootNode root = callNode != null ? callNode.getRootNode() : ((RootCallTarget) frameInstance.getCallTarget()).getRootNode(); + if (root == null || !includeInternal && root.isInternal()) { return null; } - RootNode root = callNode.getRootNode(); - if (root == null || !includeInternal && root.isInternal()) { + if (callNode == null) { + callNode = root.getLeafNodeByFrame(frameInstance); + } + if (callNode == null) { return null; } return new Caller(frameInstance, callNode); From 3f1a5c761469b4a342d478d0ec8e81b8f0280b18 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 20 Feb 2024 12:50:08 +0100 Subject: [PATCH 35/77] implement new RootNode API in EspressoRootNode. Disable stepping when resolving classes etc. (cherry picked from commit f1c1448b7eac761febc4d36e001d1d103eda404d) --- .../espresso/jdwp/api/JDWPContext.java | 2 + .../jdwp/impl/DebuggerController.java | 13 ++++++- .../truffle/espresso/EspressoLanguage.java | 16 ++++++++ .../classfile/RuntimeConstantPool.java | 21 ++++++---- .../constantpool/InvokeDynamicConstant.java | 38 ++++++++++--------- .../truffle/espresso/nodes/BciProvider.java | 3 ++ .../truffle/espresso/nodes/BytecodeNode.java | 11 ++++++ .../espresso/nodes/EspressoRootNode.java | 15 ++++++++ .../espresso/nodes/EspressoStatementNode.java | 7 ++++ .../nodes/IntrinsicSubstitutorNode.java | 5 +++ .../nodes/IntrinsifiedNativeMethodNode.java | 8 +++- .../nodes/MethodWithBytecodeNode.java | 6 +++ .../espresso/nodes/NativeMethodNode.java | 6 +++ .../espresso/nodes/bytecodes/InitCheck.java | 16 ++++++-- .../methodhandle/MHInvokeGenericNode.java | 17 +++++---- .../espresso/nodes/quick/BaseQuickNode.java | 5 +++ .../runtime/EspressoThreadLocalState.java | 15 ++++++++ .../espresso/runtime/JDWPContextImpl.java | 5 +++ .../truffle/espresso/verifier/Operand.java | 6 ++- 19 files changed, 178 insertions(+), 37 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java index f753e07f8cbc..1788e898dd89 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/JDWPContext.java @@ -503,4 +503,6 @@ public interface JDWPContext { * Tests if the thread is a virtual thread. */ boolean isVirtualThread(Object thread); + + boolean isSingleSteppingDisabled(); } diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/DebuggerController.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/DebuggerController.java index e0acff47af54..00768b728761 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/DebuggerController.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/DebuggerController.java @@ -809,7 +809,7 @@ public void onSuspend(SuspendedEvent event) { } CallFrame[] callFrames = createCallFrames(ids.getIdAsLong(currentThread), event.getStackFrames(), 1, steppingInfo); // get the top frame for checking instance filters - if (callFrames.length > 0 && checkExclusionFilters(steppingInfo, event, currentThread, callFrames[0])) { + if (checkExclusionFilters(steppingInfo, event, currentThread, callFrames[0])) { fine(() -> "not suspending here: " + event.getSourceSection()); // continue stepping until completed commandRequestIds.put(currentThread, steppingInfo); @@ -975,6 +975,13 @@ private boolean matchLocation(Pattern[] patterns, CallFrame callFrame) { private boolean checkExclusionFilters(SteppingInfo info, SuspendedEvent event, Object thread, CallFrame frame) { if (info != null) { + if (isSingleSteppingSuspended()) { + continueStepping(event, info, thread); + return true; + } + if (frame == null) { + return false; + } RequestFilter requestFilter = eventFilters.getRequestFilter(info.getRequestId()); if (requestFilter != null && requestFilter.getStepInfo() != null) { @@ -1072,6 +1079,10 @@ private CallFrame[] createCallFrames(long threadId, Iterable st } } + private boolean isSingleSteppingSuspended() { + return context.isSingleSteppingDisabled(); + } + // Truffle logging public void info(Supplier supplier) { jdwpLogger.info(supplier); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java index 19c89ad3e627..b8b49d2b7552 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java @@ -597,4 +597,20 @@ public static Path getEspressoRuntime(TruffleLanguage.Env env) { throw EspressoError.shouldNotReachHere(e); } } + + public DisableSingleStepping disableStepping() { + return new DisableSingleStepping(); + } + + public final class DisableSingleStepping implements AutoCloseable { + + private DisableSingleStepping() { + getThreadLocalState().disableSingleStepping(); + } + + @Override + public void close() { + getThreadLocalState().enableSingleStepping(); + } + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java index d1729cde8840..1c457cd54e2c 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java @@ -25,6 +25,7 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.classfile.constantpool.ClassConstant; import com.oracle.truffle.espresso.classfile.constantpool.DynamicConstant; import com.oracle.truffle.espresso.classfile.constantpool.FieldRefConstant; @@ -75,6 +76,7 @@ public PoolConstant at(int index, String description) { return pool.at(index, description); } + @SuppressWarnings("try") private Resolvable.ResolvedConstant outOfLockResolvedAt(Klass accessingKlass, int index, String description) { Resolvable.ResolvedConstant c = constants[index]; if (c == null) { @@ -82,12 +84,14 @@ private Resolvable.ResolvedConstant outOfLockResolvedAt(Klass accessingKlass, in // double check: deopt is a heavy operation. c = constants[index]; if (c == null) { - Resolvable.ResolvedConstant locallyResolved = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); - synchronized (this) { - // Triple check: non-trivial resolution - c = constants[index]; - if (c == null) { - constants[index] = c = locallyResolved; + try (EspressoLanguage.DisableSingleStepping ignored = context.getLanguage().disableStepping()) { + Resolvable.ResolvedConstant locallyResolved = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); + synchronized (this) { + // Triple check: non-trivial resolution + c = constants[index]; + if (c == null) { + constants[index] = c = locallyResolved; + } } } } @@ -95,6 +99,7 @@ private Resolvable.ResolvedConstant outOfLockResolvedAt(Klass accessingKlass, in return c; } + @SuppressWarnings("try") private Resolvable.ResolvedConstant resolvedAt(Klass accessingKlass, int index, String description) { Resolvable.ResolvedConstant c = constants[index]; if (c == null) { @@ -104,7 +109,9 @@ private Resolvable.ResolvedConstant resolvedAt(Klass accessingKlass, int index, // FIXME(peterssen): Add memory fence for array read. c = constants[index]; if (c == null) { - constants[index] = c = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); + try (EspressoLanguage.DisableSingleStepping ignored = context.getLanguage().disableStepping()) { + constants[index] = c = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); + } } } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java index 783fae2c7133..06613bdee9e4 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java @@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.classfile.ConstantPool; import com.oracle.truffle.espresso.classfile.ConstantPool.Tag; import com.oracle.truffle.espresso.classfile.RuntimeConstantPool; @@ -150,6 +151,7 @@ public boolean isResolved() { * @see RuntimeConstantPool#linkInvokeDynamic(Klass, int) */ @Override + @SuppressWarnings("try") public CallSiteLink link(RuntimeConstantPool pool, Klass accessingKlass, int thisIndex) { // Per-callsite linking CompilerAsserts.neverPartOfCompilation(); @@ -168,23 +170,25 @@ public CallSiteLink link(RuntimeConstantPool pool, Klass accessingKlass, int thi StaticObject appendix = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1], meta.getContext()); StaticObject memberName; - if (meta.getJavaVersion().varHandlesEnabled() && !meta.getJavaVersion().java19OrLater()) { - memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( - null, - accessingKlass.mirror(), - thisIndex, - bootstrapmethodMethodHandle, - name, methodType, - StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), - appendix); - } else { - memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( - null, - accessingKlass.mirror(), - bootstrapmethodMethodHandle, - name, methodType, - StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), - appendix); + try (EspressoLanguage.DisableSingleStepping ignored = meta.getLanguage().disableStepping()) { + if (meta.getJavaVersion().varHandlesEnabled() && !meta.getJavaVersion().java19OrLater()) { + memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( + null, + accessingKlass.mirror(), + thisIndex, + bootstrapmethodMethodHandle, + name, methodType, + StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), + appendix); + } else { + memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( + null, + accessingKlass.mirror(), + bootstrapmethodMethodHandle, + name, methodType, + StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), + appendix); + } } StaticObject unboxedAppendix = appendix.get(meta.getLanguage(), 0); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java index 39ecb65eb060..f8ba0ab40bad 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java @@ -23,8 +23,11 @@ package com.oracle.truffle.espresso.nodes; import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.nodes.Node; public interface BciProvider { int getBci(Frame frame); + + Node getLeafNode(int bci); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 9a6a275efe7f..3f849bb45670 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -296,6 +296,7 @@ import com.oracle.truffle.api.nodes.ControlFlowException; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.LoopNode; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.espresso.EspressoLanguage; @@ -492,6 +493,16 @@ public SourceSection getSourceSectionAtBCI(int bci) { return s.createSection(line); } + @Override + public Node getLeafNode(int bci) { + InstrumentationSupport support = instrumentation; + if (support == null) { + return null; + } + int index = support.hookBCIToNodeIndex.lookup(0, bci - 1, bci); + return support.statementNodes[index]; + } + @ExplodeLoop private void initArguments(VirtualFrame frame) { Object[] arguments = frame.getArguments(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java index 50d319fc7c8f..26bdcd612961 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java @@ -29,6 +29,7 @@ import com.oracle.truffle.api.TruffleStackTraceElement; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.instrumentation.StandardTags; import com.oracle.truffle.api.interop.TruffleObject; @@ -216,6 +217,20 @@ public final int readBCI(Frame frame) { return getMethodNode().getBci(frame); } + @Override + public Node getLeafNodeByFrame(FrameInstance frameInstance) { + Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY); + int bci = readBCI(frame); + if (bci != -1) { + Node leafNode = getMethodNode().getLeafNode(bci); + if (leafNode != null) { + assert leafNode.getRootNode() == this; + return leafNode; + } + } + return this; + } + public final void setFrameId(Frame frame, long frameId) { initCookieSlot(frame); frame.setAuxiliarySlot(cookieSlot, FrameCookie.createPrivilegedCookie(frameId)); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java index 67312da5735f..4721ddfe04fe 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java @@ -23,6 +23,7 @@ package com.oracle.truffle.espresso.nodes; import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; @@ -39,6 +40,12 @@ public final class EspressoStatementNode extends EspressoBaseStatementNode imple this.startBci = startBci; } + @Override + public Node getLeafNode(int bci) { + assert bci == startBci; + return this; + } + @Override public SourceSection getSourceSection() { Source s = getBytecodeNode().getSource(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java index 6c685c71fc89..16fa06d14638 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java @@ -91,6 +91,11 @@ public int getBci(@SuppressWarnings("unused") Frame frame) { return -2; } + @Override + public Node getLeafNode(@SuppressWarnings("unused")int bci) { + return null; + } + @Override boolean isTrivial() { return substitution.isTrivial(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java index fec2ec8a3ae5..c1a3e3b12657 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java @@ -25,6 +25,7 @@ import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.impl.Method; import com.oracle.truffle.espresso.substitutions.CallableFromNative; @@ -59,7 +60,12 @@ Object execute(VirtualFrame frame) { } @Override - public int getBci(Frame frame) { + public int getBci(@SuppressWarnings("unused") Frame frame) { return -2; } + + @Override + public Node getLeafNode(@SuppressWarnings("unused") int bci) { + return null; + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java index a91f9d85592c..4c1955a5056c 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java @@ -33,6 +33,7 @@ import com.oracle.truffle.api.interop.NodeLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.impl.SuppressFBWarnings; /** @@ -57,6 +58,11 @@ public int getBci(Frame frame) { return bytecodeNode.getBci(frame); } + @Override + public Node getLeafNode(int bci) { + return bytecodeNode.getLeafNode(bci); + } + @Override void beforeInstumentation(VirtualFrame frame) { EspressoFrame.setBCI(frame, -1); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java index 0c647f1a9900..c6485d51a763 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java @@ -33,6 +33,7 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.nodes.ExplodeLoop; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.descriptors.Signatures; import com.oracle.truffle.espresso.descriptors.Symbol; import com.oracle.truffle.espresso.descriptors.Symbol.Type; @@ -155,4 +156,9 @@ private Object processResult(JniEnv env, Object result) { public int getBci(@SuppressWarnings("unused") Frame frame) { return -2; } + + @Override + public Node getLeafNode(@SuppressWarnings("unused") int bci) { + return null; + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java index 0777c46734bd..6c2017c7635c 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.impl.ObjectKlass; import com.oracle.truffle.espresso.nodes.EspressoNode; @@ -39,33 +40,42 @@ public abstract class InitCheck extends EspressoNode { public abstract void execute(ObjectKlass klass); + @SuppressWarnings("try") @Specialization(limit = "LIMIT", guards = "cachedKlass == klass") void doCached(ObjectKlass klass, @Cached("klass") ObjectKlass cachedKlass) { if (!klass.isInitialized()) { // Deopt loop if class initialization fails. CompilerDirectives.transferToInterpreterAndInvalidate(); - cachedKlass.safeInitialize(); + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + cachedKlass.safeInitialize(); + } } } + @SuppressWarnings("try") @Specialization(replaces = "doCached") void doGeneric(ObjectKlass klass) { if (CompilerDirectives.isPartialEvaluationConstant(klass)) { if (!klass.isInitialized()) { // Deopt loop if class initialization fails. CompilerDirectives.transferToInterpreterAndInvalidate(); - klass.safeInitialize(); + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + klass.safeInitialize(); + } } } else { initCheckBoundary(klass); } } + @SuppressWarnings("try") @TruffleBoundary(allowInlining = true) static void initCheckBoundary(ObjectKlass klass) { if (!klass.isInitialized()) { - klass.safeInitialize(); + try (EspressoLanguage.DisableSingleStepping ignored = klass.getLanguage().disableStepping()) { + klass.safeInitialize(); + } } } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java index b51ae5ebcc2e..bee3e48e23d8 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java @@ -67,17 +67,20 @@ public Object call(Object[] args) { return callNode.call(args); } + @SuppressWarnings("try") public static MHInvokeGenericNode create(EspressoLanguage language, Meta meta, Klass accessingKlass, Method method, Symbol methodName, Symbol signature) { Klass callerKlass = accessingKlass == null ? meta.java_lang_Object : accessingKlass; StaticObject appendixBox = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1], meta.getContext()); // Ask java code to spin an invoker for us. - StaticObject memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkMethod.invokeDirect( - null, - callerKlass.mirror(), (int) REF_invokeVirtual, - method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), - appendixBox); - StaticObject appendix = appendixBox.get(language, 0); - return new MHInvokeGenericNode(method, memberName, appendix); + try (EspressoLanguage.DisableSingleStepping ignored = meta.getLanguage().disableStepping()) { + StaticObject memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkMethod.invokeDirect( + null, + callerKlass.mirror(), (int) REF_invokeVirtual, + method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), + appendixBox); + StaticObject appendix = appendixBox.get(language, 0); + return new MHInvokeGenericNode(method, memberName, appendix); + } } @Override diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java index 6bb5101a24d9..600d8f7915f3 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java @@ -67,6 +67,11 @@ public final BytecodeNode getBytecodeNode() { return (BytecodeNode) parent; } + @Override + public Node getLeafNode(int bci) { + return getBytecodeNode().getLeafNode(bci); + } + @ExportMessage @SuppressWarnings("static-method") public final boolean hasScope(@SuppressWarnings("unused") Frame frame) { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java index 0139ea6f1b78..5507216be427 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/EspressoThreadLocalState.java @@ -37,6 +37,8 @@ public class EspressoThreadLocalState { private StaticObject currentPlatformThread; private StaticObject currentVirtualThread; + private int singleSteppingDisabledCounter; + @SuppressWarnings("unused") public EspressoThreadLocalState(EspressoContext context) { typeStack = new ClassRegistry.TypeStack(); @@ -117,4 +119,17 @@ public ClassRegistry.TypeStack getTypeStack() { public VM.PrivilegedStack getPrivilegedStack() { return privilegedStack; } + + public void disableSingleStepping() { + singleSteppingDisabledCounter++; + } + + public void enableSingleStepping() { + assert singleSteppingDisabledCounter > 0; + singleSteppingDisabledCounter--; + } + + public boolean isSteppingDisabled() { + return singleSteppingDisabledCounter > 0; + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java index ae4061adf7c8..747aee9f7ec2 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java @@ -262,6 +262,11 @@ public boolean isVirtualThread(Object thread) { return context.getThreadAccess().isVirtualThread((StaticObject) thread); } + @Override + public boolean isSingleSteppingDisabled() { + return context.getLanguage().getThreadLocalState().isSteppingDisabled(); + } + @Override public Object[] getAllGuestThreads() { StaticObject[] activeThreads = context.getActiveThreads(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java index 16e6e378195c..609820df3e21 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java @@ -30,6 +30,7 @@ import java.util.ArrayList; +import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.descriptors.Symbol; import com.oracle.truffle.espresso.descriptors.Symbol.Type; import com.oracle.truffle.espresso.impl.Klass; @@ -237,13 +238,16 @@ Symbol getType() { } @Override + @SuppressWarnings("try") Klass getKlass() { if (klass == null) { try { if (getType() == thisKlass.getType()) { klass = thisKlass; } else { - klass = thisKlass.getMeta().resolveSymbolOrNull(type, thisKlass.getDefiningClassLoader(), thisKlass.protectionDomain()); + try (EspressoLanguage.DisableSingleStepping ignored = thisKlass.getLanguage().disableStepping()) { + klass = thisKlass.getMeta().resolveSymbolOrNull(type, thisKlass.getDefiningClassLoader(), thisKlass.protectionDomain()); + } } } catch (EspressoException e) { // TODO(garcia) fine grain this catch From 6f4e1d4bfa7c549803e0bd3c74297ab7d60b880f Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Wed, 21 Feb 2024 09:13:18 +0100 Subject: [PATCH 36/77] make sure all native and substitution methods return the root node as the leaf (cherry picked from commit 3758b8fc013ab4697790e7cdbc619b520b95457a) --- .../src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java index 26bdcd612961..c37669e7e8b2 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java @@ -221,7 +221,7 @@ public final int readBCI(Frame frame) { public Node getLeafNodeByFrame(FrameInstance frameInstance) { Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY); int bci = readBCI(frame); - if (bci != -1) { + if (bci >= 0) { Node leafNode = getMethodNode().getLeafNode(bci); if (leafNode != null) { assert leafNode.getRootNode() == this; From 58d2d0e932a69be8fc004ffcf5803804b47b1331 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Wed, 21 Feb 2024 09:14:41 +0100 Subject: [PATCH 37/77] simplify BciProvider hierarchy by providing default implementations (cherry picked from commit b8cf482b38945ca68910540017fb7fad3ed943af) --- .../oracle/truffle/espresso/nodes/BciProvider.java | 10 +++++++--- .../espresso/nodes/IntrinsicSubstitutorNode.java | 11 ----------- .../nodes/IntrinsifiedNativeMethodNode.java | 12 ------------ .../truffle/espresso/nodes/NativeMethodNode.java | 14 +------------- 4 files changed, 8 insertions(+), 39 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java index f8ba0ab40bad..faa29c9edcf0 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,11 @@ public interface BciProvider { - int getBci(Frame frame); + default int getBci(Frame frame) { + return -2; + } - Node getLeafNode(int bci); + default Node getLeafNode(int bci) { + return null; + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java index 16fa06d14638..a5b131e5a338 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java @@ -25,7 +25,6 @@ import java.util.Arrays; -import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.impl.Method; @@ -86,16 +85,6 @@ public Node copy() { return split(); } - @Override - public int getBci(@SuppressWarnings("unused") Frame frame) { - return -2; - } - - @Override - public Node getLeafNode(@SuppressWarnings("unused")int bci) { - return null; - } - @Override boolean isTrivial() { return substitution.isTrivial(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java index c1a3e3b12657..7c9d3b0079fb 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsifiedNativeMethodNode.java @@ -23,9 +23,7 @@ package com.oracle.truffle.espresso.nodes; -import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.impl.Method; import com.oracle.truffle.espresso.substitutions.CallableFromNative; @@ -58,14 +56,4 @@ Object execute(VirtualFrame frame) { } return nativeMethod.invokeDirect(env, args); } - - @Override - public int getBci(@SuppressWarnings("unused") Frame frame) { - return -2; - } - - @Override - public Node getLeafNode(@SuppressWarnings("unused") int bci) { - return null; - } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java index c6485d51a763..91f5b27a2a87 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; @@ -33,7 +32,6 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.nodes.ExplodeLoop; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.descriptors.Signatures; import com.oracle.truffle.espresso.descriptors.Symbol; import com.oracle.truffle.espresso.descriptors.Symbol.Type; @@ -151,14 +149,4 @@ private Object processResult(JniEnv env, Object result) { assert !(returnType == Type._void) || result == StaticObject.NULL; return result; } - - @Override - public int getBci(@SuppressWarnings("unused") Frame frame) { - return -2; - } - - @Override - public Node getLeafNode(@SuppressWarnings("unused") int bci) { - return null; - } } From ad3386781cf027c628b220961cc8804bdfdb56dd Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Wed, 21 Feb 2024 09:15:56 +0100 Subject: [PATCH 38/77] remove redundant class init checks since those will be done when creating foreign objects later anyway (cherry picked from commit 8ef5878363a9a42ad6da22939ce2f61450a72990) --- .../oracle/truffle/espresso/nodes/interop/ToReference.java | 3 --- ...Target_com_oracle_truffle_espresso_polyglot_Polyglot.java | 5 +---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/ToReference.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/ToReference.java index c27a27349b6c..02338eb20b80 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/ToReference.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/ToReference.java @@ -52,7 +52,6 @@ import com.oracle.truffle.espresso.meta.EspressoError; import com.oracle.truffle.espresso.meta.Meta; import com.oracle.truffle.espresso.nodes.EspressoNode; -import com.oracle.truffle.espresso.nodes.bytecodes.InitCheck; import com.oracle.truffle.espresso.nodes.bytecodes.InstanceOf; import com.oracle.truffle.espresso.runtime.EspressoContext; import com.oracle.truffle.espresso.runtime.EspressoException; @@ -1392,14 +1391,12 @@ public StaticObject doEspresso(StaticObject value, }) StaticObject doForeignInterface(Object value, @Cached.Shared("value") @CachedLibrary(limit = "LIMIT") InteropLibrary interop, - @Cached InitCheck initCheck, @Cached LookupProxyKlassNode lookupProxyKlassNode, @Cached BranchProfile errorProfile) throws UnsupportedTypeException { try { Object metaObject = getMetaObjectOrThrow(value, interop); WrappedProxyKlass proxyKlass = lookupProxyKlassNode.execute(metaObject, getMetaName(metaObject, interop), targetType); if (proxyKlass != null) { - initCheck.execute(targetType); return proxyKlass.createProxyInstance(value, getLanguage(), interop); } throw new ClassCastException(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_com_oracle_truffle_espresso_polyglot_Polyglot.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_com_oracle_truffle_espresso_polyglot_Polyglot.java index 10ee517b02f4..29896f43ed1e 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_com_oracle_truffle_espresso_polyglot_Polyglot.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_com_oracle_truffle_espresso_polyglot_Polyglot.java @@ -45,7 +45,6 @@ import com.oracle.truffle.espresso.impl.ObjectKlass; import com.oracle.truffle.espresso.impl.PrimitiveKlass; import com.oracle.truffle.espresso.meta.Meta; -import com.oracle.truffle.espresso.nodes.bytecodes.InitCheck; import com.oracle.truffle.espresso.nodes.bytecodes.InstanceOf; import com.oracle.truffle.espresso.nodes.interop.MethodArgsUtils; import com.oracle.truffle.espresso.nodes.interop.ToReference; @@ -220,13 +219,11 @@ StaticObject doForeignException( @SuppressWarnings("unused") ObjectKlass targetKlass, @JavaType(Object.class) StaticObject value, @Shared("value") @CachedLibrary(limit = "LIMIT") InteropLibrary interop, - @Cached BranchProfile exceptionProfile, - @Cached InitCheck initCheck) { + @Cached BranchProfile exceptionProfile) { Meta meta = context.getMeta(); // Casting to ForeignException skip the field checks. Object foreignObject = value.rawForeignObject(getLanguage()); if (interop.isException(foreignObject)) { - initCheck.execute(targetKlass); return StaticObject.createForeignException(context, foreignObject, interop); } exceptionProfile.enter(); From ab7434c0c708e0cc3d343c147309b3325be1cd55 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Wed, 21 Feb 2024 09:27:29 +0100 Subject: [PATCH 39/77] Skip bci check, we end up returning null from the default implementation for leaf node, so don't bother (cherry picked from commit b36616d047d9d0bdb015cce46cbc50eae205b67b) --- .../truffle/espresso/nodes/EspressoRootNode.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java index c37669e7e8b2..42b0703e15e2 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java @@ -214,19 +214,16 @@ public static EspressoRootNode createSubstitution(Method.MethodVersion methodVer } public final int readBCI(Frame frame) { - return getMethodNode().getBci(frame); + return methodNode.getBci(frame); } @Override public Node getLeafNodeByFrame(FrameInstance frameInstance) { Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY); - int bci = readBCI(frame); - if (bci >= 0) { - Node leafNode = getMethodNode().getLeafNode(bci); - if (leafNode != null) { - assert leafNode.getRootNode() == this; - return leafNode; - } + Node leafNode = methodNode.getLeafNode(readBCI(frame)); + if (leafNode != null) { + assert leafNode.getRootNode() == this; + return leafNode; } return this; } From 1e7a662dbece0f48c81f2bd29d26f4564f7196d9 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Thu, 22 Feb 2024 08:26:31 +0100 Subject: [PATCH 40/77] only attempt to get next bci when 0 or above. Takes out the -2 default bci (cherry picked from commit 5e42adae2678df45db1f6141ff94ba5ec41462dc) --- .../com/oracle/truffle/espresso/runtime/JDWPContextImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java index 747aee9f7ec2..f265b79af769 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java @@ -607,7 +607,7 @@ public int getNextBCI(RootNode callerRoot, Frame frame) { if (callerRoot instanceof EspressoRootNode) { EspressoRootNode espressoRootNode = (EspressoRootNode) callerRoot; int bci = (int) readBCIFromFrame(callerRoot, frame); - if (bci != -1) { + if (bci > -1) { BytecodeStream bs = new BytecodeStream(espressoRootNode.getMethodVersion().getOriginalCode()); return bs.nextBCI(bci); } From 03888156e6e51d5a04c6d3732409f42ace7c05c0 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Thu, 22 Feb 2024 08:29:46 +0100 Subject: [PATCH 41/77] remove disable stepping from verifier. (cherry picked from commit 2da389103cc34ad6b3769e9eec1ddff096f7c85a) --- .../src/com/oracle/truffle/espresso/verifier/Operand.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java index 609820df3e21..1265c2c057e0 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java @@ -245,9 +245,7 @@ Klass getKlass() { if (getType() == thisKlass.getType()) { klass = thisKlass; } else { - try (EspressoLanguage.DisableSingleStepping ignored = thisKlass.getLanguage().disableStepping()) { - klass = thisKlass.getMeta().resolveSymbolOrNull(type, thisKlass.getDefiningClassLoader(), thisKlass.protectionDomain()); - } + klass = thisKlass.getMeta().resolveSymbolOrNull(type, thisKlass.getDefiningClassLoader(), thisKlass.protectionDomain()); } } catch (EspressoException e) { // TODO(garcia) fine grain this catch From c68480caf336fc91d40bd27cf12625f333791cc6 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 07:08:49 +0100 Subject: [PATCH 42/77] go back to workaround for finding caller in DebuggerSession (cherry picked from commit db6bbb80f49f3d2659fb06711373d3a4b29edd59) --- .../truffle/espresso/nodes/BciProvider.java | 9 +------- .../truffle/espresso/nodes/BytecodeNode.java | 11 ---------- .../espresso/nodes/EspressoRootNode.java | 12 ----------- .../espresso/nodes/EspressoStatementNode.java | 7 ------- .../nodes/MethodWithBytecodeNode.java | 6 ------ .../truffle/api/debug/DebuggerSession.java | 7 +++---- .../oracle/truffle/api/nodes/RootNode.java | 21 ------------------- 7 files changed, 4 insertions(+), 69 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java index faa29c9edcf0..31bd084fe804 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BciProvider.java @@ -23,15 +23,8 @@ package com.oracle.truffle.espresso.nodes; import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.nodes.Node; public interface BciProvider { - default int getBci(Frame frame) { - return -2; - } - - default Node getLeafNode(int bci) { - return null; - } + int getBci(Frame frame); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 3f849bb45670..9a6a275efe7f 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -296,7 +296,6 @@ import com.oracle.truffle.api.nodes.ControlFlowException; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.LoopNode; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.espresso.EspressoLanguage; @@ -493,16 +492,6 @@ public SourceSection getSourceSectionAtBCI(int bci) { return s.createSection(line); } - @Override - public Node getLeafNode(int bci) { - InstrumentationSupport support = instrumentation; - if (support == null) { - return null; - } - int index = support.hookBCIToNodeIndex.lookup(0, bci - 1, bci); - return support.statementNodes[index]; - } - @ExplodeLoop private void initArguments(VirtualFrame frame) { Object[] arguments = frame.getArguments(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java index 42b0703e15e2..4eb478b60e36 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java @@ -29,7 +29,6 @@ import com.oracle.truffle.api.TruffleStackTraceElement; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; -import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.instrumentation.StandardTags; import com.oracle.truffle.api.interop.TruffleObject; @@ -217,17 +216,6 @@ public final int readBCI(Frame frame) { return methodNode.getBci(frame); } - @Override - public Node getLeafNodeByFrame(FrameInstance frameInstance) { - Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY); - Node leafNode = methodNode.getLeafNode(readBCI(frame)); - if (leafNode != null) { - assert leafNode.getRootNode() == this; - return leafNode; - } - return this; - } - public final void setFrameId(Frame frame, long frameId) { initCookieSlot(frame); frame.setAuxiliarySlot(cookieSlot, FrameCookie.createPrivilegedCookie(frameId)); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java index 4721ddfe04fe..67312da5735f 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoStatementNode.java @@ -23,7 +23,6 @@ package com.oracle.truffle.espresso.nodes; import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; @@ -40,12 +39,6 @@ public final class EspressoStatementNode extends EspressoBaseStatementNode imple this.startBci = startBci; } - @Override - public Node getLeafNode(int bci) { - assert bci == startBci; - return this; - } - @Override public SourceSection getSourceSection() { Source s = getBytecodeNode().getSource(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java index 4c1955a5056c..a91f9d85592c 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java @@ -33,7 +33,6 @@ import com.oracle.truffle.api.interop.NodeLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.espresso.impl.SuppressFBWarnings; /** @@ -58,11 +57,6 @@ public int getBci(Frame frame) { return bytecodeNode.getBci(frame); } - @Override - public Node getLeafNode(int bci) { - return bytecodeNode.getLeafNode(bci); - } - @Override void beforeInstumentation(VirtualFrame frame) { EspressoFrame.setBCI(frame, -1); diff --git a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java index d57407605b71..6ada3c19b509 100644 --- a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java +++ b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java @@ -1142,10 +1142,9 @@ public Caller visitFrame(FrameInstance frameInstance) { return null; } if (callNode == null) { - callNode = root.getLeafNodeByFrame(frameInstance); - } - if (callNode == null) { - return null; + // GR-52192 temporary workaround for Espresso, where a meaningful call node + // cannot always be set as encapsulated node reference. + callNode = root; } return new Caller(frameInstance, callNode); } diff --git a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java index ae2ac0aa616a..59e1d5df93b6 100644 --- a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java +++ b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java @@ -59,7 +59,6 @@ import com.oracle.truffle.api.TruffleStackTraceElement; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; -import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; @@ -592,26 +591,6 @@ protected FrameDescriptor getParentFrameDescriptor() { return null; } - /** - * If this root node supports obtaining precise location information from a frame instance, this - * method returns the leaf node corresponding to that location. The returned node must have this - * root node as a parent or be this root node itself. The passed frame instance must be the - * instance from which the reference to this root node was obtained. - *

- * This is particularly useful in situations where the frame instance doesn't have an - * instrumentable call node. Hence, the precise location {@link SourceSection} in the associated - * frame cannot be obtained. Examples where a call node is not available include languages where - * e.g. substitutions or lazy class loading trigger calls into the guest language without being - * able to (easily) obtain the current caller node. - * - * @param frameInstance the frame instance - * @return The leaf node if supported. null otherwise. - * @since 24.1.0 - */ - public Node getLeafNodeByFrame(FrameInstance frameInstance) { - return null; - } - /** * Tests if two frames are the same. This method is mainly used by instruments in case of * yield of the execution and later resume. Frame comparison is used to match the From 84067d2a069a480c60a8f3b07e245367d31f2777 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 07:10:32 +0100 Subject: [PATCH 43/77] more precise disabling of stepping when resolving constants from within ByteCodeNode (cherry picked from commit eb07c949ce150bd0225111ed45b821322a857a29) --- .../classfile/RuntimeConstantPool.java | 22 +++---- .../classfile/constantpool/ClassConstant.java | 66 ++++++++++--------- .../constantpool/InvokeDynamicConstant.java | 39 +++++------ .../truffle/espresso/nodes/BytecodeNode.java | 39 +++++++---- .../EspressoInstrumentableRootNodeImpl.java | 7 ++ .../espresso/nodes/bytecodes/InitCheck.java | 18 ++--- .../nodes/bytecodes/InvokeSpecial.java | 4 ++ .../nodes/bytecodes/InvokeStatic.java | 6 +- .../methodhandle/MHInvokeGenericNode.java | 16 ++--- .../espresso/nodes/quick/BaseQuickNode.java | 9 ++- .../quick/invoke/InvokeSpecialQuickNode.java | 8 +++ .../quick/invoke/InvokeStaticQuickNode.java | 5 ++ .../truffle/espresso/verifier/Operand.java | 1 - 13 files changed, 132 insertions(+), 108 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java index 1c457cd54e2c..fbc3f933d5d8 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.classfile.constantpool.ClassConstant; import com.oracle.truffle.espresso.classfile.constantpool.DynamicConstant; import com.oracle.truffle.espresso.classfile.constantpool.FieldRefConstant; @@ -76,7 +75,6 @@ public PoolConstant at(int index, String description) { return pool.at(index, description); } - @SuppressWarnings("try") private Resolvable.ResolvedConstant outOfLockResolvedAt(Klass accessingKlass, int index, String description) { Resolvable.ResolvedConstant c = constants[index]; if (c == null) { @@ -84,14 +82,12 @@ private Resolvable.ResolvedConstant outOfLockResolvedAt(Klass accessingKlass, in // double check: deopt is a heavy operation. c = constants[index]; if (c == null) { - try (EspressoLanguage.DisableSingleStepping ignored = context.getLanguage().disableStepping()) { - Resolvable.ResolvedConstant locallyResolved = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); - synchronized (this) { - // Triple check: non-trivial resolution - c = constants[index]; - if (c == null) { - constants[index] = c = locallyResolved; - } + Resolvable.ResolvedConstant locallyResolved = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); + synchronized (this) { + // Triple check: non-trivial resolution + c = constants[index]; + if (c == null) { + constants[index] = c = locallyResolved; } } } @@ -109,9 +105,7 @@ private Resolvable.ResolvedConstant resolvedAt(Klass accessingKlass, int index, // FIXME(peterssen): Add memory fence for array read. c = constants[index]; if (c == null) { - try (EspressoLanguage.DisableSingleStepping ignored = context.getLanguage().disableStepping()) { - constants[index] = c = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); - } + constants[index] = c = ((Resolvable) pool.at(index, description)).resolve(this, index, accessingKlass); } } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java index 56df4f7e6dcf..a366d847ffc8 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ import java.util.logging.Level; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.classfile.ConstantPool; import com.oracle.truffle.espresso.classfile.ConstantPool.Tag; import com.oracle.truffle.espresso.classfile.RuntimeConstantPool; @@ -114,39 +115,42 @@ public Symbol getName(ConstantPool pool) { * If steps 1 and 2 succeed but step 3 fails, C is still valid and usable. Nevertheless, * resolution fails, and D is prohibited from accessing C. */ + @SuppressWarnings("try") @Override public Resolved resolve(RuntimeConstantPool pool, int thisIndex, Klass accessingKlass) { - CLASS_RESOLVE_COUNT.inc(); - assert accessingKlass != null; - CompilerDirectives.transferToInterpreterAndInvalidate(); - Symbol klassName = getName(pool); - try { - EspressoContext context = pool.getContext(); - Symbol type = context.getTypes().fromName(klassName); - Klass klass = context.getMeta().resolveSymbolOrFail(type, accessingKlass.getDefiningClassLoader(), accessingKlass.protectionDomain()); - if (!Klass.checkAccess(klass.getElementalType(), accessingKlass, false)) { - Meta meta = context.getMeta(); - context.getLogger().log(Level.FINE, - "Access check of: " + klass.getType() + " from " + accessingKlass.getType() + " throws IllegalAccessError"); - throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, meta.toGuestString(klassName)); - } - - return new Resolved(klass); - - } catch (EspressoException e) { - CompilerDirectives.transferToInterpreter(); - Meta meta = pool.getContext().getMeta(); - if (meta.java_lang_ClassNotFoundException.isAssignableFrom(e.getGuestException().getKlass())) { - throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, meta.toGuestString(klassName)); + try (EspressoLanguage.DisableSingleStepping ignored = accessingKlass.getLanguage().disableStepping()) { + CLASS_RESOLVE_COUNT.inc(); + assert accessingKlass != null; + CompilerDirectives.transferToInterpreterAndInvalidate(); + Symbol klassName = getName(pool); + try { + EspressoContext context = pool.getContext(); + Symbol type = context.getTypes().fromName(klassName); + Klass klass = context.getMeta().resolveSymbolOrFail(type, accessingKlass.getDefiningClassLoader(), accessingKlass.protectionDomain()); + if (!Klass.checkAccess(klass.getElementalType(), accessingKlass, false)) { + Meta meta = context.getMeta(); + context.getLogger().log(Level.FINE, + "Access check of: " + klass.getType() + " from " + accessingKlass.getType() + " throws IllegalAccessError"); + throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, meta.toGuestString(klassName)); + } + + return new Resolved(klass); + + } catch (EspressoException e) { + CompilerDirectives.transferToInterpreter(); + Meta meta = pool.getContext().getMeta(); + if (meta.java_lang_ClassNotFoundException.isAssignableFrom(e.getGuestException().getKlass())) { + throw meta.throwExceptionWithMessage(meta.java_lang_NoClassDefFoundError, meta.toGuestString(klassName)); + } + throw e; + } catch (VirtualMachineError e) { + // Comment from Hotspot: + // Just throw the exception and don't prevent these classes from + // being loaded for virtual machine errors like StackOverflow + // and OutOfMemoryError, etc. + // Needs clarification to section 5.4.3 of the JVM spec (see 6308271) + throw e; } - throw e; - } catch (VirtualMachineError e) { - // Comment from Hotspot: - // Just throw the exception and don't prevent these classes from - // being loaded for virtual machine errors like StackOverflow - // and OutOfMemoryError, etc. - // Needs clarification to section 5.4.3 of the JVM spec (see 6308271) - throw e; } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java index 06613bdee9e4..a6300fe68b19 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.classfile.ConstantPool; import com.oracle.truffle.espresso.classfile.ConstantPool.Tag; import com.oracle.truffle.espresso.classfile.RuntimeConstantPool; @@ -170,25 +169,23 @@ public CallSiteLink link(RuntimeConstantPool pool, Klass accessingKlass, int thi StaticObject appendix = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1], meta.getContext()); StaticObject memberName; - try (EspressoLanguage.DisableSingleStepping ignored = meta.getLanguage().disableStepping()) { - if (meta.getJavaVersion().varHandlesEnabled() && !meta.getJavaVersion().java19OrLater()) { - memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( - null, - accessingKlass.mirror(), - thisIndex, - bootstrapmethodMethodHandle, - name, methodType, - StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), - appendix); - } else { - memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( - null, - accessingKlass.mirror(), - bootstrapmethodMethodHandle, - name, methodType, - StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), - appendix); - } + if (meta.getJavaVersion().varHandlesEnabled() && !meta.getJavaVersion().java19OrLater()) { + memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( + null, + accessingKlass.mirror(), + thisIndex, + bootstrapmethodMethodHandle, + name, methodType, + StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), + appendix); + } else { + memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkCallSite.invokeDirect( + null, + accessingKlass.mirror(), + bootstrapmethodMethodHandle, + name, methodType, + StaticObject.createArray(meta.java_lang_Object_array, args.clone(), meta.getContext()), + appendix); } StaticObject unboxedAppendix = appendix.get(meta.getLanguage(), 0); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 9a6a275efe7f..1bc200a2ba96 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2028,6 +2028,7 @@ private int quickenInstanceOf(VirtualFrame frame, int top, int curBCI, int opcod return 0; // Bytecodes.stackEffectOf(opcode); } + @SuppressWarnings("try") private int quickenInvoke(VirtualFrame frame, int top, int curBCI, int opcode, int statementIndex) { QUICKENED_INVOKES.inc(); CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -2039,6 +2040,10 @@ private int quickenInvoke(VirtualFrame frame, int top, int curBCI, int opcode, i Method resolutionSeed = resolveMethod(opcode, cpi); return dispatchQuickened(top, curBCI, cpi, opcode, statementIndex, resolutionSeed, getContext().getEspressoEnv().bytecodeLevelInlining); }); + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + // whenever possible, we should do a one-time class initialization during quickening + quick.initializeResolvedKlass(); + } // Perform the call outside of the lock. return quick.execute(frame) - Bytecodes.stackEffectOf(opcode); } @@ -2332,6 +2337,7 @@ private RuntimeException throwBoundary(ObjectKlass exceptionKlass, String messag throw getMeta().throwExceptionWithMessage(exceptionKlass, String.format(Locale.ENGLISH, messageFormat, (Object[]) args)); } + @SuppressWarnings("try") private int quickenInvokeDynamic(final VirtualFrame frame, int top, int curBCI, int opcode) { CompilerDirectives.transferToInterpreterAndInvalidate(); assert (Bytecodes.INVOKEDYNAMIC == opcode); @@ -2355,7 +2361,6 @@ private int quickenInvokeDynamic(final VirtualFrame frame, int top, int curBCI, // Do invocation outside of the lock. return quick.execute(frame) - Bytecodes.stackEffectOf(opcode); } - // Resolution should happen outside of the bytecode patching lock. InvokeDynamicConstant.CallSiteLink link = pool.linkInvokeDynamic(getMethod().getDeclaringKlass(), indyIndex); @@ -2571,6 +2576,7 @@ private long checkNonZero(long value) { * curBCI = bs.next(curBCI); * */ + @SuppressWarnings("try") private int putField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) { assert opcode == PUTFIELD || opcode == PUTSTATIC; CompilerAsserts.partialEvaluationConstant(field); @@ -2635,11 +2641,15 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o int slotCount = (typeHeader == 'J' || typeHeader == 'D') ? 2 : 1; assert slotCount == field.getKind().getSlotCount(); int slot = top - slotCount - 1; // -receiver - StaticObject receiver = (opcode == PUTSTATIC) - ? field.getDeclaringKlass().tryInitializeAndGetStatics() - // Do not release the object, it might be read again in PutFieldNode - : nullCheck(popObject(frame, slot)); - + StaticObject receiver; + if (opcode == PUTSTATIC) { + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + receiver = field.getDeclaringKlass().tryInitializeAndGetStatics(); + } + } else { + // Do not release the object, it might be read again in PutFieldNode + receiver = nullCheck(popObject(frame, slot)); + } if (!noForeignObjects.isValid() && opcode == PUTFIELD) { if (receiver.isForeignObject()) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -2732,6 +2742,7 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o * curBCI = bs.next(curBCI); * */ + @SuppressWarnings("try") private int getField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) { assert opcode == GETFIELD || opcode == GETSTATIC; @@ -2755,11 +2766,15 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o assert field.isStatic() == (opcode == GETSTATIC); int slot = top - 1; - StaticObject receiver = opcode == GETSTATIC - ? field.getDeclaringKlass().tryInitializeAndGetStatics() - // Do not release the object, it might be read again in GetFieldNode - : nullCheck(peekObject(frame, slot)); - + StaticObject receiver; + if (opcode == GETSTATIC) { + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + receiver = field.getDeclaringKlass().tryInitializeAndGetStatics(); + } + } else { + // Do not release the object, it might be read again in GetFieldNode + receiver = nullCheck(peekObject(frame, slot)); + } if (!noForeignObjects.isValid() && opcode == GETFIELD) { if (receiver.isForeignObject()) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoInstrumentableRootNodeImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoInstrumentableRootNodeImpl.java index 42f2c821dbdb..2ee625ba3eff 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoInstrumentableRootNodeImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoInstrumentableRootNodeImpl.java @@ -23,12 +23,14 @@ package com.oracle.truffle.espresso.nodes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.instrumentation.StandardTags; import com.oracle.truffle.api.instrumentation.Tag; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.espresso.impl.Method.MethodVersion; import com.oracle.truffle.espresso.meta.EspressoError; +import com.oracle.truffle.espresso.vm.VM; /** * Base node for all implementations of Java methods. @@ -96,4 +98,9 @@ public boolean hasTag(Class tag) { } return false; } + + @Override + public int getBci(Frame frame) { + return VM.EspressoStackElement.NATIVE_BCI; + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java index 6c2017c7635c..7a2274824567 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InitCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.NodeInfo; -import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.impl.ObjectKlass; import com.oracle.truffle.espresso.nodes.EspressoNode; @@ -40,42 +39,33 @@ public abstract class InitCheck extends EspressoNode { public abstract void execute(ObjectKlass klass); - @SuppressWarnings("try") @Specialization(limit = "LIMIT", guards = "cachedKlass == klass") void doCached(ObjectKlass klass, @Cached("klass") ObjectKlass cachedKlass) { if (!klass.isInitialized()) { // Deopt loop if class initialization fails. CompilerDirectives.transferToInterpreterAndInvalidate(); - try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - cachedKlass.safeInitialize(); - } + cachedKlass.safeInitialize(); } } - @SuppressWarnings("try") @Specialization(replaces = "doCached") void doGeneric(ObjectKlass klass) { if (CompilerDirectives.isPartialEvaluationConstant(klass)) { if (!klass.isInitialized()) { // Deopt loop if class initialization fails. CompilerDirectives.transferToInterpreterAndInvalidate(); - try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - klass.safeInitialize(); - } + klass.safeInitialize(); } } else { initCheckBoundary(klass); } } - @SuppressWarnings("try") @TruffleBoundary(allowInlining = true) static void initCheckBoundary(ObjectKlass klass) { if (!klass.isInitialized()) { - try (EspressoLanguage.DisableSingleStepping ignored = klass.getLanguage().disableStepping()) { - klass.safeInitialize(); - } + klass.safeInitialize(); } } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java index 3968c7c24646..8261bda1c267 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java @@ -88,6 +88,10 @@ public abstract static class WithoutNullCheck extends EspressoNode { this.method = method; } + public Method getMethod() { + return method; + } + public abstract Object execute(Object[] args); static StaticObject getReceiver(Object[] args) { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeStatic.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeStatic.java index a7ddffae1324..bf28015256dd 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeStatic.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,10 @@ public abstract class InvokeStatic extends EspressoNode { this.staticMethod = staticMethod; } + public Method getStaticMethod() { + return staticMethod; + } + public abstract Object execute(Object[] args); @Specialization diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java index bee3e48e23d8..33dfa6f71e16 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java @@ -72,15 +72,13 @@ public static MHInvokeGenericNode create(EspressoLanguage language, Meta meta, K Klass callerKlass = accessingKlass == null ? meta.java_lang_Object : accessingKlass; StaticObject appendixBox = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1], meta.getContext()); // Ask java code to spin an invoker for us. - try (EspressoLanguage.DisableSingleStepping ignored = meta.getLanguage().disableStepping()) { - StaticObject memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkMethod.invokeDirect( - null, - callerKlass.mirror(), (int) REF_invokeVirtual, - method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), - appendixBox); - StaticObject appendix = appendixBox.get(language, 0); - return new MHInvokeGenericNode(method, memberName, appendix); - } + StaticObject memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkMethod.invokeDirect( + null, + callerKlass.mirror(), (int) REF_invokeVirtual, + method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), + appendixBox); + StaticObject appendix = appendixBox.get(language, 0); + return new MHInvokeGenericNode(method, memberName, appendix); } @Override diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java index 600d8f7915f3..091fce8ed1a4 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java @@ -67,11 +67,6 @@ public final BytecodeNode getBytecodeNode() { return (BytecodeNode) parent; } - @Override - public Node getLeafNode(int bci) { - return getBytecodeNode().getLeafNode(bci); - } - @ExportMessage @SuppressWarnings("static-method") public final boolean hasScope(@SuppressWarnings("unused") Frame frame) { @@ -87,4 +82,8 @@ public final Object getScope(Frame frame, boolean nodeEnter) { private Object getScopeSlowPath(MaterializedFrame frame, boolean nodeEnter) { return getBytecodeNode().getScope(frame, nodeEnter); } + + public void initializeResolvedKlass() { + // do nothing by default + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java index 9f756ba39910..81c58419529b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java @@ -23,6 +23,7 @@ package com.oracle.truffle.espresso.nodes.quick.invoke; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.espresso.descriptors.Symbol; import com.oracle.truffle.espresso.impl.Method; import com.oracle.truffle.espresso.nodes.bytecodes.InvokeSpecial; import com.oracle.truffle.espresso.nodes.bytecodes.InvokeSpecialNodeGen; @@ -44,4 +45,11 @@ public int execute(VirtualFrame frame) { nullCheck((StaticObject) args[0]); return pushResult(frame, invokeSpecial.execute(args)); } + + @Override + public void initializeResolvedKlass() { + if (Symbol.Name._init_.equals(method.getName())) { + method.getDeclaringKlass().safeInitialize(); + } + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java index 9861fc2e81a2..ad16ce9c8f2b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java @@ -56,4 +56,9 @@ public int execute(VirtualFrame frame) { Object[] args = getArguments(frame); return pushResult(frame, invokeStatic.execute(args)); } + + @Override + public void initializeResolvedKlass() { + invokeStatic.getStaticMethod().getDeclaringKlass().safeInitialize(); + } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java index 1265c2c057e0..a86e31817434 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java @@ -238,7 +238,6 @@ Symbol getType() { } @Override - @SuppressWarnings("try") Klass getKlass() { if (klass == null) { try { From 073a26bb26748ca13ddf9c93efe4d2dda66c4ceb Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 07:11:59 +0100 Subject: [PATCH 44/77] make sure to search for the instrumentable espresso root node when locating a BciProvider from a root node (cherry picked from commit 7327984a7c265e34d2367df77f3cfecf696cdbad) --- .../truffle/espresso/runtime/JDWPContextImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java index f265b79af769..afa7e6193b36 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java @@ -691,9 +691,9 @@ public Class> getLanguageClass() { return EspressoLanguage.class; } - private static BciProvider getBciProviderNode(Node node) { - if (node instanceof BciProvider) { - return (BciProvider) node; + private BciProvider getBciProviderNode(Node node) { + if (node instanceof BciProvider bciProvider) { + return bciProvider; } Node currentNode = node.getParent(); while (currentNode != null) { @@ -702,6 +702,10 @@ private static BciProvider getBciProviderNode(Node node) { } currentNode = currentNode.getParent(); } + Node instrumentableNode = getInstrumentableNode(node.getRootNode()); + if (instrumentableNode instanceof BciProvider bciProvider) { + return bciProvider; + } return null; } From 291b9a4d96446b0c92beeb02996c14c3f1f2e6a9 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 11:10:40 +0100 Subject: [PATCH 45/77] unused import (cherry picked from commit 7f7b06cc5089e49a85091e8b51f92cb9cae58d05) --- .../src/com/oracle/truffle/espresso/verifier/Operand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java index a86e31817434..16e6e378195c 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/verifier/Operand.java @@ -30,7 +30,6 @@ import java.util.ArrayList; -import com.oracle.truffle.espresso.EspressoLanguage; import com.oracle.truffle.espresso.descriptors.Symbol; import com.oracle.truffle.espresso.descriptors.Symbol.Type; import com.oracle.truffle.espresso.impl.Klass; From 3507a722d428987c9c66c720aa32fb0a5d804ff6 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 11:34:51 +0100 Subject: [PATCH 46/77] reformat code (cherry picked from commit 2ab06df8ea4e3e3a3121a321c8a06a201bb659cd) --- .../espresso/classfile/constantpool/ClassConstant.java | 2 +- .../espresso/nodes/methodhandle/MHInvokeGenericNode.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java index a366d847ffc8..c78672860c38 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/ClassConstant.java @@ -130,7 +130,7 @@ public Resolved resolve(RuntimeConstantPool pool, int thisIndex, Klass accessing if (!Klass.checkAccess(klass.getElementalType(), accessingKlass, false)) { Meta meta = context.getMeta(); context.getLogger().log(Level.FINE, - "Access check of: " + klass.getType() + " from " + accessingKlass.getType() + " throws IllegalAccessError"); + "Access check of: " + klass.getType() + " from " + accessingKlass.getType() + " throws IllegalAccessError"); throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, meta.toGuestString(klassName)); } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java index 33dfa6f71e16..6e3173e7a298 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java @@ -73,10 +73,10 @@ public static MHInvokeGenericNode create(EspressoLanguage language, Meta meta, K StaticObject appendixBox = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1], meta.getContext()); // Ask java code to spin an invoker for us. StaticObject memberName = (StaticObject) meta.java_lang_invoke_MethodHandleNatives_linkMethod.invokeDirect( - null, - callerKlass.mirror(), (int) REF_invokeVirtual, - method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), - appendixBox); + null, + callerKlass.mirror(), (int) REF_invokeVirtual, + method.getDeclaringKlass().mirror(), meta.toGuestString(methodName), meta.toGuestString(signature), + appendixBox); StaticObject appendix = appendixBox.get(language, 0); return new MHInvokeGenericNode(method, memberName, appendix); } From 8fa723cbea05d71eafe2dfbff02f1fceefeb3c20 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 14:18:11 +0100 Subject: [PATCH 47/77] minor review fixes (cherry picked from commit aa50bf2d458d8e8f2d48f7ac418992d540616604) --- .../oracle/truffle/espresso/classfile/RuntimeConstantPool.java | 1 - .../espresso/classfile/constantpool/InvokeDynamicConstant.java | 1 - .../src/com/oracle/truffle/espresso/nodes/BytecodeNode.java | 2 -- .../espresso/nodes/methodhandle/MHInvokeGenericNode.java | 1 - .../com/oracle/truffle/espresso/runtime/JDWPContextImpl.java | 2 +- 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java index fbc3f933d5d8..0e220bf7373b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/RuntimeConstantPool.java @@ -95,7 +95,6 @@ private Resolvable.ResolvedConstant outOfLockResolvedAt(Klass accessingKlass, in return c; } - @SuppressWarnings("try") private Resolvable.ResolvedConstant resolvedAt(Klass accessingKlass, int index, String description) { Resolvable.ResolvedConstant c = constants[index]; if (c == null) { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java index a6300fe68b19..93854d0b1810 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/constantpool/InvokeDynamicConstant.java @@ -150,7 +150,6 @@ public boolean isResolved() { * @see RuntimeConstantPool#linkInvokeDynamic(Klass, int) */ @Override - @SuppressWarnings("try") public CallSiteLink link(RuntimeConstantPool pool, Klass accessingKlass, int thisIndex) { // Per-callsite linking CompilerAsserts.neverPartOfCompilation(); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 1bc200a2ba96..c6e06cf5143b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -2576,7 +2576,6 @@ private long checkNonZero(long value) { * curBCI = bs.next(curBCI); * */ - @SuppressWarnings("try") private int putField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) { assert opcode == PUTFIELD || opcode == PUTSTATIC; CompilerAsserts.partialEvaluationConstant(field); @@ -2742,7 +2741,6 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o * curBCI = bs.next(curBCI); * */ - @SuppressWarnings("try") private int getField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) { assert opcode == GETFIELD || opcode == GETSTATIC; diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java index 6e3173e7a298..b51ae5ebcc2e 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MHInvokeGenericNode.java @@ -67,7 +67,6 @@ public Object call(Object[] args) { return callNode.call(args); } - @SuppressWarnings("try") public static MHInvokeGenericNode create(EspressoLanguage language, Meta meta, Klass accessingKlass, Method method, Symbol methodName, Symbol signature) { Klass callerKlass = accessingKlass == null ? meta.java_lang_Object : accessingKlass; StaticObject appendixBox = StaticObject.createArray(meta.java_lang_Object_array, new StaticObject[1], meta.getContext()); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java index afa7e6193b36..8ce25fa7dffc 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/JDWPContextImpl.java @@ -607,7 +607,7 @@ public int getNextBCI(RootNode callerRoot, Frame frame) { if (callerRoot instanceof EspressoRootNode) { EspressoRootNode espressoRootNode = (EspressoRootNode) callerRoot; int bci = (int) readBCIFromFrame(callerRoot, frame); - if (bci > -1) { + if (bci >= 0) { BytecodeStream bs = new BytecodeStream(espressoRootNode.getMethodVersion().getOriginalCode()); return bs.nextBCI(bci); } From 0948c93489165b572200de8f2465b624d7bdb872 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 14:20:45 +0100 Subject: [PATCH 48/77] only do class init for invoke static opcodes (cherry picked from commit 5f639e4d561b14be834b10a5fbe1e2da0140e835) --- .../truffle/espresso/nodes/BytecodeNode.java | 23 +++++++++++-------- .../nodes/bytecodes/InvokeSpecial.java | 4 ---- .../espresso/nodes/quick/BaseQuickNode.java | 4 ---- .../quick/invoke/InvokeSpecialQuickNode.java | 7 ------ .../quick/invoke/InvokeStaticQuickNode.java | 1 - 5 files changed, 14 insertions(+), 25 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index c6e06cf5143b..33c9ac045450 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -2040,9 +2040,10 @@ private int quickenInvoke(VirtualFrame frame, int top, int curBCI, int opcode, i Method resolutionSeed = resolveMethod(opcode, cpi); return dispatchQuickened(top, curBCI, cpi, opcode, statementIndex, resolutionSeed, getContext().getEspressoEnv().bytecodeLevelInlining); }); - try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - // whenever possible, we should do a one-time class initialization during quickening - quick.initializeResolvedKlass(); + if (opcode == INVOKESTATIC && quick instanceof InvokeStaticQuickNode invokeStaticQuickNode) { + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + invokeStaticQuickNode.initializeResolvedKlass(); + } } // Perform the call outside of the lock. return quick.execute(frame) - Bytecodes.stackEffectOf(opcode); @@ -2642,9 +2643,7 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o int slot = top - slotCount - 1; // -receiver StaticObject receiver; if (opcode == PUTSTATIC) { - try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - receiver = field.getDeclaringKlass().tryInitializeAndGetStatics(); - } + receiver = getStaticsBoundary(field); } else { // Do not release the object, it might be read again in PutFieldNode receiver = nullCheck(popObject(frame, slot)); @@ -2730,6 +2729,14 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o return -slotCount; } + @TruffleBoundary + @SuppressWarnings("try") + private StaticObject getStaticsBoundary(Field field) { + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + return field.getDeclaringKlass().tryInitializeAndGetStatics(); + } + } + /** * Returns the stack effect (slot delta) that cannot be inferred solely from the bytecode. e.g. * PUTFIELD always pops the receiver, but the result size (1 or 2) is unknown. @@ -2766,9 +2773,7 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o int slot = top - 1; StaticObject receiver; if (opcode == GETSTATIC) { - try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - receiver = field.getDeclaringKlass().tryInitializeAndGetStatics(); - } + receiver = getStaticsBoundary(field); } else { // Do not release the object, it might be read again in GetFieldNode receiver = nullCheck(peekObject(frame, slot)); diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java index 8261bda1c267..3968c7c24646 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InvokeSpecial.java @@ -88,10 +88,6 @@ public abstract static class WithoutNullCheck extends EspressoNode { this.method = method; } - public Method getMethod() { - return method; - } - public abstract Object execute(Object[] args); static StaticObject getReceiver(Object[] args) { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java index 091fce8ed1a4..6bb5101a24d9 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/BaseQuickNode.java @@ -82,8 +82,4 @@ public final Object getScope(Frame frame, boolean nodeEnter) { private Object getScopeSlowPath(MaterializedFrame frame, boolean nodeEnter) { return getBytecodeNode().getScope(frame, nodeEnter); } - - public void initializeResolvedKlass() { - // do nothing by default - } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java index 81c58419529b..7d1aec896c43 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java @@ -45,11 +45,4 @@ public int execute(VirtualFrame frame) { nullCheck((StaticObject) args[0]); return pushResult(frame, invokeSpecial.execute(args)); } - - @Override - public void initializeResolvedKlass() { - if (Symbol.Name._init_.equals(method.getName())) { - method.getDeclaringKlass().safeInitialize(); - } - } } diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java index ad16ce9c8f2b..ea576da6c4d3 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeStaticQuickNode.java @@ -57,7 +57,6 @@ public int execute(VirtualFrame frame) { return pushResult(frame, invokeStatic.execute(args)); } - @Override public void initializeResolvedKlass() { invokeStatic.getStaticMethod().getDeclaringKlass().safeInitialize(); } From b1ae61e9011979ebb1d86f9b2eb52b4cc584d74c Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 14:55:10 +0100 Subject: [PATCH 49/77] unused import (cherry picked from commit 2a68e697751c6047174ec7b248e34d32013b7414) --- .../espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java | 1 - 1 file changed, 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java index 7d1aec896c43..9f756ba39910 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/InvokeSpecialQuickNode.java @@ -23,7 +23,6 @@ package com.oracle.truffle.espresso.nodes.quick.invoke; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.espresso.descriptors.Symbol; import com.oracle.truffle.espresso.impl.Method; import com.oracle.truffle.espresso.nodes.bytecodes.InvokeSpecial; import com.oracle.truffle.espresso.nodes.bytecodes.InvokeSpecialNodeGen; From 1d9afbed011058cb5d9aa07137cc46ca5fc19ad7 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Tue, 27 Feb 2024 19:56:20 +0100 Subject: [PATCH 50/77] minor code formatting fix (cherry picked from commit aa8461c60c0f421a0a08c667ef14a50d05d72253) --- .../src/com/oracle/truffle/espresso/nodes/BytecodeNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 33c9ac045450..23e585878db4 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -2733,7 +2733,7 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o @SuppressWarnings("try") private StaticObject getStaticsBoundary(Field field) { try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - return field.getDeclaringKlass().tryInitializeAndGetStatics(); + return field.getDeclaringKlass().tryInitializeAndGetStatics(); } } From a497548ed43006465a57ad461a716cb53712ca0e Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Wed, 28 Feb 2024 12:08:58 +0100 Subject: [PATCH 51/77] don't apply the workaround to use the root node if there was a call node available, but no nodes in node hierarchy were instrumentable (cherry picked from commit ba7979da447a7cfcf610cc373a99a2b5a4070d8e) --- .../src/com/oracle/truffle/api/debug/DebuggerSession.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java index 6ada3c19b509..b8a8812b7d05 100644 --- a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java +++ b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -1134,6 +1134,7 @@ public Caller visitFrame(FrameInstance frameInstance) { return null; } Node callNode = frameInstance.getCallNode(); + boolean callNodeAvailable = callNode != null; while (callNode != null && !SourceSectionFilter.ANY.includes(callNode)) { callNode = callNode.getParent(); } @@ -1144,6 +1145,11 @@ public Caller visitFrame(FrameInstance frameInstance) { if (callNode == null) { // GR-52192 temporary workaround for Espresso, where a meaningful call node // cannot always be set as encapsulated node reference. + if (callNodeAvailable) { + // Call node was available but no instrumentable node in parent node + // hierarchy, so we can't use the root node as the call node. + return null; + } callNode = root; } return new Caller(frameInstance, callNode); From 93fa7bef050f8882df6550f473a8f9cc5adb2190 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Fri, 1 Mar 2024 13:14:52 +0100 Subject: [PATCH 52/77] simplify method (cherry picked from commit 09d1ab8b70453c2fb204172508cb21b3a1d6c5bb) --- .../truffle/api/debug/DebuggerSession.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java index b8a8812b7d05..a81b1c786507 100644 --- a/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java +++ b/truffle/src/com.oracle.truffle.api.debug/src/com/oracle/truffle/api/debug/DebuggerSession.java @@ -1133,24 +1133,26 @@ public Caller visitFrame(FrameInstance frameInstance) { if (!SuspendedEvent.isEvalRootStackFrame(session, frameInstance) && (depth++ == 0)) { return null; } + Node callNode = frameInstance.getCallNode(); - boolean callNodeAvailable = callNode != null; - while (callNode != null && !SourceSectionFilter.ANY.includes(callNode)) { - callNode = callNode.getParent(); - } - RootNode root = callNode != null ? callNode.getRootNode() : ((RootCallTarget) frameInstance.getCallTarget()).getRootNode(); - if (root == null || !includeInternal && root.isInternal()) { - return null; - } + RootNode rootNode; if (callNode == null) { // GR-52192 temporary workaround for Espresso, where a meaningful call node // cannot always be set as encapsulated node reference. - if (callNodeAvailable) { - // Call node was available but no instrumentable node in parent node - // hierarchy, so we can't use the root node as the call node. + rootNode = ((RootCallTarget) frameInstance.getCallTarget()).getRootNode(); + callNode = rootNode; + } else { + while (callNode != null && !SourceSectionFilter.ANY.includes(callNode)) { + callNode = callNode.getParent(); + } + rootNode = callNode != null ? callNode.getRootNode() : null; + if (rootNode == null) { + // can't handle disconnected call nodes return null; } - callNode = root; + } + if (!includeInternal && rootNode.isInternal()) { + return null; } return new Caller(frameInstance, callNode); } From 717634db32792958ccc9174a2194976af0465aff Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Fri, 1 Mar 2024 13:15:19 +0100 Subject: [PATCH 53/77] remove suppressed warning (cherry picked from commit 329fe7467d1e1da7aacd245ab9405dfff667abef) --- .../src/com/oracle/truffle/espresso/nodes/BytecodeNode.java | 1 - 1 file changed, 1 deletion(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 23e585878db4..95512cb14bdf 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -2338,7 +2338,6 @@ private RuntimeException throwBoundary(ObjectKlass exceptionKlass, String messag throw getMeta().throwExceptionWithMessage(exceptionKlass, String.format(Locale.ENGLISH, messageFormat, (Object[]) args)); } - @SuppressWarnings("try") private int quickenInvokeDynamic(final VirtualFrame frame, int top, int curBCI, int opcode) { CompilerDirectives.transferToInterpreterAndInvalidate(); assert (Bytecodes.INVOKEDYNAMIC == opcode); From 8ed087a104c82e0ce00c46da15944242e480d544 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Mon, 4 Mar 2024 07:18:43 +0100 Subject: [PATCH 54/77] refactor boundary call and use transfer to interpreter when disabling stepping while potentially doing class initialization (cherry picked from commit eb12110011852f0653741b325bb6520164d928a7) --- .../truffle/espresso/nodes/BytecodeNode.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 95512cb14bdf..7fcd40c17beb 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -2642,7 +2642,7 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o int slot = top - slotCount - 1; // -receiver StaticObject receiver; if (opcode == PUTSTATIC) { - receiver = getStaticsBoundary(field); + receiver = initializeAndGetStatics(field); } else { // Do not release the object, it might be read again in PutFieldNode receiver = nullCheck(popObject(frame, slot)); @@ -2728,14 +2728,6 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o return -slotCount; } - @TruffleBoundary - @SuppressWarnings("try") - private StaticObject getStaticsBoundary(Field field) { - try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { - return field.getDeclaringKlass().tryInitializeAndGetStatics(); - } - } - /** * Returns the stack effect (slot delta) that cannot be inferred solely from the bytecode. e.g. * PUTFIELD always pops the receiver, but the result size (1 or 2) is unknown. @@ -2772,7 +2764,7 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o int slot = top - 1; StaticObject receiver; if (opcode == GETSTATIC) { - receiver = getStaticsBoundary(field); + receiver = initializeAndGetStatics(field); } else { // Do not release the object, it might be read again in GetFieldNode receiver = nullCheck(peekObject(frame, slot)); @@ -2819,6 +2811,17 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o return slotCount; } + private StaticObject initializeAndGetStatics(Field field) { + ObjectKlass declaringKlass = field.getDeclaringKlass(); + if (!declaringKlass.isInitialized()) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + try (EspressoLanguage.DisableSingleStepping ignored = getLanguage().disableStepping()) { + declaringKlass.safeInitialize(); + } + } + return declaringKlass.getStatics(); + } + // endregion Field read/write @Override From b66084053e5d7404da5cc92ed39c28ea84642bf4 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Mon, 4 Mar 2024 08:18:58 +0100 Subject: [PATCH 55/77] suppress warning (cherry picked from commit 366778eff1c1c62a845967eeffc68089113fdf5e) --- .../src/com/oracle/truffle/espresso/nodes/BytecodeNode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java index 7fcd40c17beb..b82b6c9f45d9 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java @@ -2811,6 +2811,7 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o return slotCount; } + @SuppressWarnings("try") private StaticObject initializeAndGetStatics(Field field) { ObjectKlass declaringKlass = field.getDeclaringKlass(); if (!declaringKlass.isInitialized()) { From dfe0563e7017b7d1213a8e2ff6808d39de425450 Mon Sep 17 00:00:00 2001 From: Fabio Niephaus Date: Mon, 19 Feb 2024 09:43:33 +0100 Subject: [PATCH 56/77] Fix an incorrect option. Thanks to @faermanj for pointing this out. (cherry picked from commit fc835ab1ca4971c8c9e202f5012463294a76192c) --- docs/reference-manual/native-image/MemoryManagement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference-manual/native-image/MemoryManagement.md b/docs/reference-manual/native-image/MemoryManagement.md index 59d3bac9695f..e6a2cd3e0e15 100644 --- a/docs/reference-manual/native-image/MemoryManagement.md +++ b/docs/reference-manual/native-image/MemoryManagement.md @@ -164,7 +164,7 @@ Here is a small subset of the options that can be specified when doing performan ```shell # Build and execute a native image that uses the G1 GC with a region size of 2MB and a maximum pause time goal of 100ms -native-image --gc=G1 -H:G1RegionSize=2m -R:MaxGCPauseMillis=100 HelloWorld +native-image --gc=G1 -H:G1HeapRegionSize=2m -R:MaxGCPauseMillis=100 HelloWorld ./helloworld # Execute the native image from above and override the maximum pause time goal From 900e7abce77e5594f248a70f4f0f3731036e79aa Mon Sep 17 00:00:00 2001 From: Fabio Niephaus Date: Mon, 19 Feb 2024 10:43:08 +0100 Subject: [PATCH 57/77] Fix printed values in `-march` user errors. (cherry picked from commit 2423486e84588c6b9de7a2a1407d9186626b626d) --- .../src/com/oracle/svm/hosted/util/CPUType.java | 7 ++++++- .../src/com/oracle/svm/hosted/util/CPUTypeAArch64.java | 4 ++-- .../src/com/oracle/svm/hosted/util/CPUTypeAMD64.java | 4 ++-- .../src/com/oracle/svm/hosted/util/CPUTypeRISCV64.java | 8 ++++---- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUType.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUType.java index b333a8e8f83e..5b9e66fb8ba6 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUType.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.Comparator; +import java.util.List; import org.graalvm.nativeimage.Platform; @@ -86,4 +87,8 @@ static String getSelectedOrDefaultMArch() { return "unknown"; } } + + static List toNames(CPUType[] values) { + return Arrays.stream(values).map(CPUType::getName).toList(); + } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAArch64.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAArch64.java index a32ab66e440f..23e625f00abb 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAArch64.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAArch64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,7 +133,7 @@ public static EnumSet getCPUFeaturesForArch(String marchValue) { throw UserError.abort("Unsupported architecture '%s'. Please adjust '%s'. On AArch64, only %s are available.", marchValue, SubstrateOptionsParser.commandArgument(NativeImageOptions.MicroArchitecture, marchValue), - StringUtil.joinSingleQuoted(values())); + StringUtil.joinSingleQuoted(CPUType.toNames(values()))); } List features = new ArrayList<>(value.getFeatures()); processFeatureModifiers(features, archParts); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java index 0dd5f1f9efc1..dc84c524b3ac 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeAMD64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,7 +177,7 @@ public static EnumSet getCPUFeaturesForArch(String marchValue) { throw UserError.abort("Unsupported architecture '%s'. Please adjust '%s'. On AMD64, only %s are available.", marchValue, SubstrateOptionsParser.commandArgument(NativeImageOptions.MicroArchitecture, marchValue), - StringUtil.joinSingleQuoted(values())); + StringUtil.joinSingleQuoted(CPUType.toNames(values()))); } return value.getFeatures(); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeRISCV64.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeRISCV64.java index 2cfb0e334d6a..9212f4e5a6fd 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeRISCV64.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/util/CPUTypeRISCV64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,7 +91,7 @@ private static CPUFeature[] getNativeOrEmpty() { name = cpuTypeName; parent = cpuTypeParentOrNull; specificFeatures = features.length > 0 ? EnumSet.copyOf(List.of(features)) : EnumSet.noneOf(CPUFeature.class); - assert parent == null || parent.getFeatures().stream().noneMatch(f -> specificFeatures.contains(f)) : "duplicate features detected but not allowed"; + assert parent == null || parent.getFeatures().stream().noneMatch(specificFeatures::contains) : "duplicate features detected but not allowed"; } @Override @@ -106,7 +106,7 @@ public CPUTypeRISCV64 getParent() { @Override public String getSpecificFeaturesString() { - return specificFeatures.stream().map(f -> f.name()).collect(Collectors.joining(" + ")); + return specificFeatures.stream().map(Enum::name).collect(Collectors.joining(" + ")); } public EnumSet getFeatures() { @@ -136,7 +136,7 @@ public static EnumSet getCPUFeaturesForArch(String marchValue) { throw UserError.abort("Unsupported architecture '%s'. Please adjust '%s'. On RISCV64, only %s are available.", marchValue, SubstrateOptionsParser.commandArgument(NativeImageOptions.MicroArchitecture, marchValue), - StringUtil.joinSingleQuoted(values())); + StringUtil.joinSingleQuoted(CPUType.toNames(values()))); } return value.getFeatures(); } From 7270b532ef54e9a2fa5f2b73e773ff0dff2bcebb Mon Sep 17 00:00:00 2001 From: Fabio Niephaus Date: Mon, 19 Feb 2024 10:43:38 +0100 Subject: [PATCH 58/77] Document `-O` and `-march` options. (cherry picked from commit 139e092105911e21b589cdca15d6e117544c73ed) --- .../OptimizationsAndPerformance.md | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/reference-manual/native-image/OptimizationsAndPerformance.md b/docs/reference-manual/native-image/OptimizationsAndPerformance.md index 7f2323e25b75..6e72dd4f14d3 100644 --- a/docs/reference-manual/native-image/OptimizationsAndPerformance.md +++ b/docs/reference-manual/native-image/OptimizationsAndPerformance.md @@ -7,7 +7,35 @@ permalink: /reference-manual/native-image/optimizations-and-performance/ # Optimizations and Performance -Native Image provides advanced mechanisms to further optimize the generated binary: +Native Image provides different mechanisms that enable users to optimize a generated binary in terms of performance, file size, build time, debuggability, and other metrics. + +### Optimization Levels + +Similar to `gcc` and `clang`, users can control the optimization level using the `-O` option. +By default, `-O2` is used which aims for a good tradeoff between performance, file size, and build time. +The following table provides an overview of the different optimization levels and explains when they are useful: + +| Level | Optimizations | Use Cases | +|:---:|:---:|---| +| `-Ob` | Reduced | Quick build mode: Speeds up builds during development by avoiding time-consuming optimizations. This can also reduce file size sometimes. | +| `-O0` | None | Typically used together with `-g` to improve the debugging experience. | +| `-O1` | Basic | Trades performance for reduced file size and build time. Oracle GraalVM's `-O1` is somewhat comparable to `-O2` in GraalVM Community Edition. | +| `-O2` | Advanced | **Default:** Aims for good performance at a reasonable file size. | +| `-O3` | All | Aims for the best performance at the cost of longer build times. Used automatically by Oracle GraalVM for [PGO builds](guides/optimize-native-executable-with-pgo.md) (`--pgo` option). `-O3` and `-O2` are identical in GraalVM Community Edition. | + +### Optimizing for Specific Machines + +Native Image provides a `-march` option that works similarly to the ones in `gcc` and `clang`: it enables users to control the set of instructions that the Graal compiler can use when compiling code to native. +By default, Native Image uses [`x86-64-v3` on x64](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels){:target="_blank"} and [`armv8-a` on AArch64](https://en.wikipedia.org/wiki/ARM_architecture_family#Cores){:target="_blank"}. +Use `-march=list` to list all available machine types. +If the generated binary is built on the same or similar machine type that it is also deployed on, use `-march=native`. +This option instructs the compiler to use all instructions that it finds available on the machine the binary is generated on. +If the generated binary, on the other hand, is distributed to users with many different, and potentially very old machines, use `-march=compatibility`. +This reduces the set of instructions used by the compiler to a minimum and thus improves the compatibility of the generated binary. + +### Additional Features + +Native Image provides additional features to further optimize a generated binary: - Profile-Guided Optimizations (PGO) can provide additional performance gain and higher throughput for most native images. See [Optimize a Native Executable with PGO](guides/optimize-native-executable-with-pgo.md). - Choosing an appropriate Garbage Collector and tailoring the garbage collection policy can reduce GC times. See [Memory Management](MemoryManagement.md). From d5c625e02aa475e359bb8b7691a68f655d383e74 Mon Sep 17 00:00:00 2001 From: Fabio Niephaus Date: Tue, 20 Feb 2024 10:47:53 +0100 Subject: [PATCH 59/77] Document list of build artifacts. (cherry picked from commit 9802d5750de4bec78e9e851c324d9e754cfd1702) --- .../reference-manual/native-image/BuildOutput.md | 15 +++++++++++++-- .../assets/build-artifacts-schema-v0.9.0.json | 16 ++++++++-------- .../com/oracle/svm/hosted/ProgressReporter.java | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/reference-manual/native-image/BuildOutput.md b/docs/reference-manual/native-image/BuildOutput.md index c3cdbfadf68a..ac33a412d124 100644 --- a/docs/reference-manual/native-image/BuildOutput.md +++ b/docs/reference-manual/native-image/BuildOutput.md @@ -66,7 +66,7 @@ Recommendations: -------------------------------------------------------------------------------- 0.8s (4.6% of total time) in 35 GCs | Peak RSS: 1.93GB | CPU load: 9.61 -------------------------------------------------------------------------------- -Produced artifacts: +Build artifacts: /home/janedoe/helloworld/helloworld (executable) /home/janedoe/helloworld/helloworld.debug (debug_info) /home/janedoe/helloworld/sources (debug_info) @@ -341,11 +341,22 @@ If there is enough headroom and the [GC statistics](#glossary-garbage-collection The CPU time used by the process divided by the total process time. Increase the number of CPU cores to reduce the time to build the native binary. +## Build Artifacts + +The list of all build artifacts. +This includes the generated native binary, but it can also contain other artifacts such as additional libraries, C header files, or debug info. +Some of these artifacts must remain in the same location with the native binary as they are needed at run time. +For applications using AWT, for example, the build process will also output libraries from the JDK and shims to provide compatible AWT support. +These libraries need to be copied and distributed together with the native binary. +Use the `-H:+GenerateBuildArtifactsFile` option to instruct the builder to produce a machine-readable version of the build artifact list in JSON format. +Such a JSON file validates against the JSON schema defined in [`build-artifacts-schema-v0.9.0.json`](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json). +This schema also contains descriptions for each possible artifact type and explains whether they are needed at run time or not. + ## Machine-Readable Build Output The build output produced by the `native-image` builder is designed for humans, can evolve with new releases, and should thus not be parsed in any way by tools. Instead, use the `-H:BuildOutputJSONFile=` option to instruct the builder to produce machine-readable build output in JSON format that can be used, for example, for building monitoring tools. -The JSON files validate against the JSON schema defined in [`build-output-schema-v0.9.2.json`](https://github.com/oracle/graal/tree/master/docs/reference-manual/native-image/assets/build-output-schema-v0.9.2.json). +Such a JSON file validates against the JSON schema defined in [`build-output-schema-v0.9.2.json`](https://github.com/oracle/graal/tree/master/docs/reference-manual/native-image/assets/build-output-schema-v0.9.2.json). Note that a JSON file is produced if and only if a build succeeds. The following example illustrates how this could be used in a CI/CD build pipeline to check that the number of reachable methods does not exceed a certain threshold: diff --git a/docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json b/docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json index bb120d232f1a..0cd2059a233b 100644 --- a/docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json +++ b/docs/reference-manual/native-image/assets/build-artifacts-schema-v0.9.0.json @@ -11,7 +11,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "Build information generated by Native Image (not needed at run-time)", + "title": "Build information generated by Native Image (not needed at run time)", "type": "array" }, "c_headers": { @@ -21,7 +21,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "C header files generated by Native Image (not needed at run-time)", + "title": "C header files generated by Native Image (not needed at run time)", "type": "array" }, "debug_info": { @@ -31,7 +31,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "Debug information generated by Native Image (not needed at run-time)", + "title": "Debug information generated by Native Image (not needed at run time)", "type": "array" }, "executables": { @@ -41,7 +41,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "Executables generated by Native Image (needed at run-time)", + "title": "Executables generated by Native Image (needed at run time)", "type": "array" }, "import_libraries": { @@ -51,7 +51,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "Import libraries generated by Native Image (not needed at run-time)", + "title": "Import libraries generated by Native Image (not needed at run time)", "type": "array" }, "jdk_libraries": { @@ -61,7 +61,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "JDK libraries copied by Native Image (needed at run-time)", + "title": "JDK libraries copied by Native Image (needed at run time)", "type": "array" }, "language_home": { @@ -71,7 +71,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "Language home artifacts for Truffle languages (needed at run-time)", + "title": "Language home artifacts for Truffle languages (needed at run time)", "type": "array" }, "shared_libraries": { @@ -81,7 +81,7 @@ "title": "Relative path to file or directory", "type": "string" }, - "title": "Shared libraries generated by Native Image (not needed at run-time)", + "title": "Shared libraries generated by Native Image (needed at run time)", "type": "array" } }, diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java index b61004f2c439..2bbb7b5e1b7d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ProgressReporter.java @@ -778,7 +778,7 @@ private void printArtifacts(Map> artifacts) { return; } l().printLineSeparator(); - l().yellowBold().a("Produced artifacts:").reset().println(); + l().yellowBold().doclink("Build artifacts", "#glossary-build-artifacts").a(":").reset().println(); // Use TreeMap to sort paths alphabetically. Map> pathToTypes = new TreeMap<>(); artifacts.forEach((artifactType, paths) -> { From 84b5a7440c6d37bf41076337875369909303a3aa Mon Sep 17 00:00:00 2001 From: Josef Eisl Date: Fri, 15 Mar 2024 15:15:54 +0100 Subject: [PATCH 60/77] ci: reenable labsjdk-ee-latest vs oraclejdk-latest assert --- ci/common.jsonnet | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ci/common.jsonnet b/ci/common.jsonnet index c0794d82065f..56723c5129a4 100644 --- a/ci/common.jsonnet +++ b/ci/common.jsonnet @@ -64,6 +64,15 @@ local common_json = import "../common.json"; # We do not want to expose galahad-jdk assert std.assertEqual([x for x in std.objectFields(common_json.jdks) if x != "galahad-jdk"], std.objectFields(jdks_data)), # Verify oraclejdk-latest and labsjdk-ee-latest versions match + assert + local _labsjdk = common_json.jdks["labsjdk-ee-latest"]; + local _oraclejdk = common_json.jdks["oraclejdk-latest"]; + local _ov = _oraclejdk.build_id; + local _lv = std.strReplace(_labsjdk.version, "ee-", "jdk-"); + # Skip the check if we are not using a labsjdk. This can happen on JDK integration branches. + local no_labsjdk = _labsjdk.name != "labsjdk"; + assert no_labsjdk || std.startsWith(_lv, _ov) : "update oraclejdk-latest to match labsjdk-ee-latest: %s+%s vs %s" % [_oraclejdk.version, _oraclejdk.build_id, _labsjdk.version]; + true, # The raw jdk data, the same as common_json.jdks + { jdk_version:: } jdks_data: jdks_data, From b4a1c41ddd87f51f39bb86f30967b0020f951d64 Mon Sep 17 00:00:00 2001 From: Josef Eisl Date: Fri, 15 Mar 2024 15:20:38 +0100 Subject: [PATCH 61/77] ci: update oraclejdk-latest to jdk-22.0.1+8 --- common.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.json b/common.json index 1cc275111362..1156d5a19a4e 100644 --- a/common.json +++ b/common.json @@ -44,7 +44,7 @@ "labsjdk-ee-21Debug": {"name": "labsjdk", "version": "ee-21.0.1+11-jvmci-23.1-b26-debug", "platformspecific": true }, "labsjdk-ee-21-llvm": {"name": "labsjdk", "version": "ee-21.0.1+11-jvmci-23.1-b26-sulong", "platformspecific": true }, - "oraclejdk-latest": {"name": "jpg-jdk", "version": "22", "build_id": "36", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, + "oraclejdk-latest": {"name": "jpg-jdk", "version": "22", "build_id": "jdk-22.0.1+8", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01", "platformspecific": true }, "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-debug", "platformspecific": true }, "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-sulong", "platformspecific": true }, From 1b917118899918526b2315aab56dada83b5c8699 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Fri, 15 Mar 2024 17:14:24 +0000 Subject: [PATCH 62/77] do not use release artifacts --- common.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.json b/common.json index 1156d5a19a4e..3f46910e350c 100644 --- a/common.json +++ b/common.json @@ -44,7 +44,7 @@ "labsjdk-ee-21Debug": {"name": "labsjdk", "version": "ee-21.0.1+11-jvmci-23.1-b26-debug", "platformspecific": true }, "labsjdk-ee-21-llvm": {"name": "labsjdk", "version": "ee-21.0.1+11-jvmci-23.1-b26-sulong", "platformspecific": true }, - "oraclejdk-latest": {"name": "jpg-jdk", "version": "22", "build_id": "jdk-22.0.1+8", "release": true, "platformspecific": true, "extrabundles": ["static-libs"]}, + "oraclejdk-latest": {"name": "jpg-jdk", "version": "22", "build_id": "jdk-22.0.1+8", "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01", "platformspecific": true }, "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-debug", "platformspecific": true }, "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-22.0.1+8-jvmci-b01-sulong", "platformspecific": true }, From 06f31df4de92a4258cf531b103933ba0676531c8 Mon Sep 17 00:00:00 2001 From: Jan Stola Date: Mon, 18 Mar 2024 20:03:38 +0000 Subject: [PATCH 63/77] [GR-52466] Backport to 24.0: Upgrading the underlying Node.js to version 18.19.1. PullRequest: js/3084 --- vm/mx.vm/suite.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 829c20443a82..b8fdcf06c169 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -33,7 +33,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "f2e7ec76a9b09262a636fcd3072dd22f89a9a0e6", + "version": "c103057cc9d9805c1c72afd95448b59775eacad0", "urls" : [ {"url" : "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] @@ -42,7 +42,7 @@ "name": "graal-js", "subdir": True, "dynamic": True, - "version": "f2e7ec76a9b09262a636fcd3072dd22f89a9a0e6", + "version": "c103057cc9d9805c1c72afd95448b59775eacad0", "urls": [ {"url": "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] From dd4b2140474976cb928f88c543bce034a6cde27d Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Mon, 22 Jan 2024 09:53:09 +0100 Subject: [PATCH 64/77] [GR-51529] FileSystemsTest#testSetAttribute() fails on JDK-23-linux. (cherry picked from commit 433b90a318293d446cb913ce1c59d77721c16f98) --- .../api/test/polyglot/FileSystemsTest.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/FileSystemsTest.java b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/FileSystemsTest.java index 32adfe0011b4..c7fd137dbe37 100644 --- a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/FileSystemsTest.java +++ b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/FileSystemsTest.java @@ -2044,7 +2044,7 @@ public void testSetAttribute() throws IOException { boolean canRead = cfg.canRead(); boolean canWrite = cfg.canWrite(); AbstractExecutableTestLanguage.evalTestLanguage(ctx, TestSetAttributeLanguage.class, "", configuration, path, usePublicFile, canRead, canWrite, supportsUnixAttributes(), - supportsSetLastAccessTime()); + supportsSetLastAccessTime(), supportsSetCreationTime()); } @Registration @@ -2059,6 +2059,7 @@ protected Object execute(RootNode node, Env env, Object[] contextArguments, Obje boolean canWrite = (boolean) contextArguments[4]; boolean supportsUnixAttributes = (boolean) contextArguments[5]; boolean supportsSetLastAccessTime = (boolean) contextArguments[6]; + boolean supportsSetCreationTime = (boolean) contextArguments[7]; TruffleFile root = resolve(env, usePublicFile, path); try { TruffleFile file = root.resolve(FILE_CHANGE_ATTRS); @@ -2067,14 +2068,18 @@ protected Object execute(RootNode node, Env env, Object[] contextArguments, Obje Assert.assertTrue(formatErrorMessage("Expected SecurityException", configurationName, path), canWrite); Assert.assertEquals(time, file.getAttribute(TruffleFile.LAST_MODIFIED_TIME)); Assert.assertTrue(formatErrorMessage("Expected SecurityException", configurationName, path), canRead); + file.setAttribute(TruffleFile.LAST_ACCESS_TIME, time); + FileTime lastAccessTime = file.getAttribute(TruffleFile.LAST_ACCESS_TIME); // Workaround for issue JDK-8298187: The file last access time does not work on // JDK-20 on macOS with the hfs file system. if (supportsSetLastAccessTime) { - file.setAttribute(TruffleFile.LAST_ACCESS_TIME, time); - Assert.assertEquals(time, file.getAttribute(TruffleFile.LAST_ACCESS_TIME)); + Assert.assertEquals(time, lastAccessTime); } file.setAttribute(TruffleFile.CREATION_TIME, time); - Assert.assertEquals(time, file.getAttribute(TruffleFile.CREATION_TIME)); + FileTime creationTime = file.getAttribute(TruffleFile.CREATION_TIME); + if (supportsSetCreationTime) { + Assert.assertEquals(time, creationTime); + } file.setAttribute(TruffleFile.UNIX_PERMISSIONS, EnumSet.of(PosixFilePermission.OWNER_READ)); Assert.assertEquals(EnumSet.of(PosixFilePermission.OWNER_READ), file.getAttribute(TruffleFile.UNIX_PERMISSIONS)); file.setAttribute(TruffleFile.UNIX_PERMISSIONS, EnumSet.of(PosixFilePermission.OWNER_READ)); @@ -2106,6 +2111,17 @@ private boolean supportsSetLastAccessTime() throws IOException { return true; } + /** + * Returns {@code true} if the operating system supports file creation time modification. Note: + * Posix does not support setting a file's creation time directly. MacOS and BSD Unix, however, + * provide an additional system call {@code fsetattrlist} utilized by Java NIO to set the + * creation time. On Linux, the Posix functions {@code utimes}, {@code futimens}, or + * {@code utimensat} are employed, allowing modification only of access and modification times. + */ + private static boolean supportsSetCreationTime() { + return OSUtils.isWindows() || OSUtils.getCurrent() == OSUtils.OS.Darwin; + } + @Test public void testGetAttributes() throws IOException { Context ctx = cfg.getContext(); From 4c2a30b311e510a26fc7cf8f4d47dfdc983a0588 Mon Sep 17 00:00:00 2001 From: Raphael Mosaner Date: Wed, 13 Mar 2024 16:36:10 +0100 Subject: [PATCH 65/77] [GR-52657] Fix simplification of always-deopt FixedGuard. (cherry picked from commit 1b7238b93811e3335fa58d4b64e0f7dd39bcefd1) --- .../test/FixedGuardSimplificationTest.java | 136 ++++++++++++++++++ .../graal/compiler/nodes/FixedGuardNode.java | 14 +- 2 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/FixedGuardSimplificationTest.java diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/FixedGuardSimplificationTest.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/FixedGuardSimplificationTest.java new file mode 100644 index 000000000000..51c2c2a135c2 --- /dev/null +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/FixedGuardSimplificationTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.graal.compiler.core.test; + +import org.junit.Test; + +import jdk.graal.compiler.api.directives.GraalDirectives; +import jdk.graal.compiler.core.common.type.StampFactory; +import jdk.graal.compiler.nodes.FixedGuardNode; +import jdk.graal.compiler.nodes.GraphState; +import jdk.graal.compiler.nodes.PiNode; +import jdk.graal.compiler.nodes.StructuredGraph; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.java.LoadFieldNode; +import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.phases.BasePhase; +import jdk.graal.compiler.phases.tiers.HighTierContext; +import jdk.graal.compiler.phases.tiers.Suites; +import jdk.graal.compiler.virtual.phases.ea.FinalPartialEscapePhase; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.meta.DeoptimizationAction; +import jdk.vm.ci.meta.DeoptimizationReason; + +/** + * Tests that correct removal of always deoptimizing {@link FixedGuardNode}s in the presence of + * floating reads. This test modifies the graph after PEA to introduce a {@link FixedGuardNode} in a + * branch which is dominated by another {@link FixedGuardNode} with the inverted condition. + * Replacing the always-deopt guard must ensure a proper cleanup of all attached floating reads. + * This is tested by a floating read for which the removed guard ensures non-nullness of the read + * object. If this read would survive the removal of the guard, a segfault would be triggered. The + * guard branch is deleted in midtier after conditional elimination. + */ +public class FixedGuardSimplificationTest extends GraalCompilerTest { + + public static class A { + B b; + + public A(B b) { + this.b = b; + } + } + + public static class B { + A a; + } + + public static void snippet(A a, A a2, int x) { + guardingNull(a); + if (x == 0) { + // a2 is replaced by a1 after FinalPEA + guardingNonNull(a2); + B b = a.b; + A ba = b.a; + GraalDirectives.blackhole(ba); + } + } + + @Override + protected Suites createSuites(OptionValues opts) { + Suites s = super.createSuites(opts); + s.getHighTier().findPhase(FinalPartialEscapePhase.class).add(new BasePhase() { + + @Override + protected void run(StructuredGraph graph, HighTierContext context) { + FixedGuardNode guard = graph.getNodes().filter(FixedGuardNode.class).first(); + FixedGuardNode placeholderGuard = graph.getNodes().filter(FixedGuardNode.class).snapshot().get(1); + + /* + * Makes the inner guard use the inverted condition of the dominating, outer guard + * and adds the corresponding Pi. This can happen during PartialEscapeAnalysis. + */ + placeholderGuard.setCondition(guard.getCondition(), true); + ValueNode nullProven = (ValueNode) guard.getCondition().asNode().inputs().first(); + PiNode pi = (PiNode) graph.addWithoutUnique(PiNode.create(nullProven, StampFactory.objectNonNull(), placeholderGuard)); + LoadFieldNode lf = graph.getNodes().filter(LoadFieldNode.class).first(); + lf.setObject(pi); + } + + @Override + public java.util.Optional notApplicableTo(GraphState graphState) { + return ALWAYS_APPLICABLE; + } + }); + return s; + } + + private static T guardingNull(T value) { + if (value != null) { + GraalDirectives.deoptimize(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode, true); + } + return value; + } + + private static T guardingNonNull(T value) { + if (value == null) { + GraalDirectives.deoptimize(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode, true); + } + return value; + } + + @Test + public void test() throws InvalidInstalledCodeException { + InstalledCode code = getCode(getResolvedJavaMethod("snippet")); + boolean exceptionSeen = false; + try { + code.executeVarargs(null, new A(new B()), 0); + } catch (NullPointerException npe) { + exceptionSeen = true; + } + assert exceptionSeen : "Test expects a NPE to be thrown!"; + assert !code.isValid() : "Test expects the code to have deopted!"; + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/FixedGuardNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/FixedGuardNode.java index dd7514bc3870..2c5dd1ffdf20 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/FixedGuardNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/FixedGuardNode.java @@ -39,6 +39,7 @@ import jdk.graal.compiler.nodes.spi.LoweringTool; import jdk.graal.compiler.nodes.spi.SimplifierTool; import jdk.graal.compiler.nodes.spi.SwitchFoldable; +import jdk.graal.compiler.nodes.util.GraphUtil; import jdk.graal.compiler.nodes.calc.IntegerEqualsNode; import jdk.vm.ci.meta.DeoptimizationAction; @@ -77,14 +78,15 @@ public void simplify(SimplifierTool tool) { if (getCondition() instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) getCondition(); if (c.getValue() == isNegated()) { - FixedNode currentNext = this.next(); - if (currentNext != null) { - tool.deleteBranch(currentNext); - } - + /* + * The guard will always deoptimize. Replace the guard and the remaining branch with + * the corresponding deopt. + */ DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason(), getSpeculation())); deopt.setStateBefore(stateBefore()); - setNext(deopt); + predecessor().replaceFirstSuccessor(this, deopt); + GraphUtil.killCFG(this); + return; } if (hasUsages()) { /* From 24856454507610fe75a6443dc49d937c27e9574a Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Wed, 13 Mar 2024 13:52:09 +0100 Subject: [PATCH 66/77] pi node: guard against deletion in recursion (cherry picked from commit 3e3e0f05d43cf878e3e332814945b0a4a55d9e91) --- .../src/jdk/graal/compiler/nodes/PiNode.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java index 767fa85689d8..3e64a566aec3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java @@ -27,6 +27,9 @@ import static jdk.graal.compiler.nodeinfo.NodeCycles.CYCLES_0; import static jdk.graal.compiler.nodeinfo.NodeSize.SIZE_0; +import java.util.List; + +import jdk.graal.compiler.core.common.SuppressFBWarnings; import jdk.graal.compiler.core.common.type.AbstractPointerStamp; import jdk.graal.compiler.core.common.type.FloatStamp; import jdk.graal.compiler.core.common.type.ObjectStamp; @@ -240,7 +243,10 @@ public void virtualize(VirtualizerTool tool) { } } + @SuppressFBWarnings(value = {"NP"}, justification = "We null check it before") public static ValueNode canonical(ValueNode object, Stamp piStamp, GuardingNode guard, ValueNode self) { + GraalError.guarantee(piStamp != null && object != null, "Invariant piStamp=%s object=%s guard=%s self=%s", piStamp, object, guard, self); + // Use most up to date stamp. Stamp computedStamp = piStamp.improveWith(object.stamp(NodeView.DEFAULT)); @@ -320,7 +326,9 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean if (guardNode.hasNoUsages()) { return; } - for (PiNode pi : guardNode.usages().filter(PiNode.class).snapshot()) { + + List pis = guardNode.usages().filter(PiNode.class).snapshot(); + for (PiNode pi : pis) { if (!pi.isAlive()) { continue; } @@ -330,6 +338,8 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean } /* + * RECURSE CALL + * * If there are PiNodes still anchored at this guard then either they must simplify away * because they are no longer necessary or this node must be replaced with a * ValueAnchorNode because the type injected by the PiNode is only true at this point in @@ -343,6 +353,16 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean tryEvacuate(tool, otherGuard, false); } } + /* + * A note on the RECURSE CALL above: When we have pis with input pis on the same guard + * (which should actually be combined) it can be that the recurse call (processing the + * same pis again) already deletes this node (very special stamp setups necessary). + * Thus, it can be that pi is dead at this point already, so we have to check for this + * again. + */ + if (!pi.isAlive()) { + continue; + } Node canonical = pi.canonical(tool); if (canonical != pi) { if (!canonical.isAlive()) { From 558d1edd4803de5a870db925b3c9b34714e30e45 Mon Sep 17 00:00:00 2001 From: Jan Stola Date: Fri, 22 Mar 2024 10:02:12 +0000 Subject: [PATCH 67/77] [GR-52840] Backport to 24.0: Instanceof operator should check whether the left side is a (foreign) object. PullRequest: js/3102 --- vm/mx.vm/suite.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index b8fdcf06c169..6e5ade08eb28 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -33,7 +33,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "c103057cc9d9805c1c72afd95448b59775eacad0", + "version": "7db28239f0da1087baf9c409fdb206b423c991b6", "urls" : [ {"url" : "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] @@ -42,7 +42,7 @@ "name": "graal-js", "subdir": True, "dynamic": True, - "version": "c103057cc9d9805c1c72afd95448b59775eacad0", + "version": "7db28239f0da1087baf9c409fdb206b423c991b6", "urls": [ {"url": "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] From bf0bb9bbfe346fe1b0868a56790e4d3fb9f0392e Mon Sep 17 00:00:00 2001 From: Andrii Konchyn Date: Tue, 26 Mar 2024 10:32:28 +0000 Subject: [PATCH 68/77] Backport [GR-18163] Fix rb_global_variable() for Float and bignum values during the Init_ function to 24.0.1 PullRequest: truffleruby/4218 --- vm/mx.vm/suite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 6e5ade08eb28..bb13696e107a 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -49,7 +49,7 @@ }, { "name": "truffleruby", - "version": "a69cf909e42ce23399152d2e90e614f49c88e9a5", + "version": "264c7e0aa54d165c2d143054248098e6db0204e5", "dynamic": True, "urls": [ {"url": "https://github.com/oracle/truffleruby.git", "kind": "git"}, From 7e9d49fae46c54a71e1cc33d20a3b0b013b0526e Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Tue, 26 Mar 2024 10:40:33 +0100 Subject: [PATCH 69/77] [GR-52921] Remove DumpTopDeoptimizedFrame. --- .../oracle/svm/core/SubstrateDiagnostics.java | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java index 6f23b899a910..6d5cc22ce0d8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateDiagnostics.java @@ -718,32 +718,6 @@ public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLev } } - private static class DumpTopDeoptimizedFrame extends DiagnosticThunk { - @Override - public int maxInvocationCount() { - return 1; - } - - @Override - @RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Must not allocate while printing diagnostics.") - public void printDiagnostics(Log log, ErrorContext context, int maxDiagnosticLevel, int invocationCount) { - Pointer sp = context.getStackPointer(); - CodePointer ip = context.getInstructionPointer(); - - if (sp.isNonNull() && ip.isNonNull()) { - long totalFrameSize = getTotalFrameSize(sp, ip); - DeoptimizedFrame deoptFrame = Deoptimizer.checkDeoptimized(sp); - if (deoptFrame != null) { - log.string("Top frame info:").indent(true); - log.string("RSP ").zhex(sp).string(" frame was deoptimized:").newline(); - log.string("SourcePC ").zhex(deoptFrame.getSourcePC()).newline(); - log.string("SourceTotalFrameSize ").signed(totalFrameSize).newline(); - log.indent(false); - } - } - } - } - private static class DumpThreads extends DiagnosticThunk { @Override public int maxInvocationCount() { @@ -1254,9 +1228,6 @@ public static synchronized DiagnosticThunkRegistry singleton() { thunks.add(new DumpRegisters()); thunks.add(new DumpInstructions()); thunks.add(new DumpTopOfCurrentThreadStack()); - if (RuntimeCompilation.isEnabled()) { - thunks.add(new DumpTopDeoptimizedFrame()); - } thunks.add(new DumpCurrentThreadLocals()); thunks.add(new DumpCurrentThreadFrameAnchors()); thunks.add(new DumpCurrentThreadDecodedStackTrace()); From 1a1990247ef06be3fc1317b99d309d4c3dba43f1 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Tue, 26 Mar 2024 10:40:58 +0100 Subject: [PATCH 70/77] [GR-52921] Mark installDeoptimizedFrame() as @Uninterruptible. --- .../src/com/oracle/svm/core/deopt/Deoptimizer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java index ddd18c93344c..6a6269fa6b19 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java @@ -257,6 +257,7 @@ private static RuntimeException checkDeoptimizedError0(Pointer sourceSp) { throw VMError.shouldNotReachHere("Unable to retrieve Deoptimized frame"); } + @Uninterruptible(reason = "Prevent stack walks from seeing an inconsistent stack.") private static void installDeoptimizedFrame(Pointer sourceSp, DeoptimizedFrame deoptimizedFrame) { /* * Replace the return address to the deoptimized method with a pointer to the deoptStub. From 5e5eb61ee901c42436e555004cf1f03560fb4bb7 Mon Sep 17 00:00:00 2001 From: Danilo Ansaloni Date: Thu, 15 Feb 2024 19:32:58 +0100 Subject: [PATCH 71/77] Move checkstyle file. (cherry picked from commit 8d9b868f67498656fc0969f11dcfbe56aa668974) --- vm/mx.vm/suite.py | 10 +++++----- .../.checkstyle_checks.xml | 0 2 files changed, 5 insertions(+), 5 deletions(-) rename vm/src/{org.graalvm.component.installer => org.graalvm.polybench}/.checkstyle_checks.xml (100%) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index bb13696e107a..8df577803094 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -88,7 +88,7 @@ "sourceDirs" : ["src"], "javaCompliance" : "17+", "license" : "GPLv2-CPE", - "checkstyleVersion" : "10.7.0", + "checkstyle": "org.graalvm.polybench", "dependencies": [ "sdk:LAUNCHER_COMMON", "truffle:TRUFFLE_JSON", @@ -103,7 +103,7 @@ "org.graalvm.component.installer" ], "javaCompliance" : "17+", - "checkstyle": "org.graalvm.component.installer", + "checkstyle": "org.graalvm.polybench", "license" : "GPLv2-CPE", "requires" : ["java.logging"], }, @@ -112,7 +112,7 @@ "sourceDirs" : ["src"], "javaCompliance" : "17+", "license" : "GPLv2-CPE", - "checkstyle": "org.graalvm.component.installer", + "checkstyleVersion" : "10.7.0", "dependencies": [ "sdk:LAUNCHER_COMMON", "sdk:POLYGLOT", @@ -128,7 +128,7 @@ "sourceDirs" : ["src"], "javaCompliance" : "17+", "license" : "GPLv2-CPE", - "checkstyle": "org.graalvm.component.installer", + "checkstyle": "org.graalvm.polybench", "dependencies": [ "truffle:TRUFFLE_API", ], @@ -142,7 +142,7 @@ "sourceDirs" : ["src"], "javaCompliance" : "17+", "license" : "GPLv2-CPE", - "checkstyle": "org.graalvm.component.installer", + "checkstyle": "org.graalvm.polybench", "dependencies": [ "truffle:TRUFFLE_API", ], diff --git a/vm/src/org.graalvm.component.installer/.checkstyle_checks.xml b/vm/src/org.graalvm.polybench/.checkstyle_checks.xml similarity index 100% rename from vm/src/org.graalvm.component.installer/.checkstyle_checks.xml rename to vm/src/org.graalvm.polybench/.checkstyle_checks.xml From 97f9971d5f08d9b63125f02dcd07268768823b14 Mon Sep 17 00:00:00 2001 From: Danilo Ansaloni Date: Tue, 6 Feb 2024 12:04:05 +0100 Subject: [PATCH 72/77] Remove the GraalVM Component Updater (gu). (cherry picked from commit ad293a2cfedee50ef05329e18ba4539c2e552082) --- sdk/mx.sdk/mx_sdk_vm_impl.py | 233 +- vm/ci/ci_common/common.jsonnet | 50 +- vm/ci/ci_includes/vm.jsonnet | 22 +- vm/mx.vm/gu-deprecated | 41 - vm/mx.vm/gu-deprecated.cmd | 35 - vm/mx.vm/gu.cmd | 70 - vm/mx.vm/mx_vm.py | 63 +- vm/mx.vm/mx_vm_gate.py | 11 - vm/mx.vm/suite.py | 88 - ...component.installer.ComponentArchiveReader | 1 - ...omponent.installer.SoftwareChannel$Factory | 1 - .../installer/CatalogIterableTest.java | 394 - .../installer/ChunkedConnection.java | 105 - .../component/installer/CommandTestBase.java | 310 - .../installer/ComponentInstallerTest.java | 581 - .../installer/DirectoryArchiveReader.java | 49 - .../installer/DownloadURLIterableTest.java | 100 - .../component/installer/EnvironmentTest.java | 241 - .../installer/InstallerCommandlineTest.java | 739 -- .../component/installer/MemoryFeedback.java | 304 - .../installer/MockURLConnection.java | 77 - .../component/installer/SimpleGetoptTest.java | 410 - .../component/installer/SystemUtilsTest.java | 142 - .../graalvm/component/installer/TestBase.java | 754 -- .../component/installer/VersionTest.java | 140 - .../installer/commands/AvailableTest.java | 253 - .../installer/commands/BlockedFileOps.java | 111 - .../commands/CatalogInstallTest.java | 667 -- .../installer/commands/InfoTest.java | 202 - .../installer/commands/InstallTest.java | 460 - .../commands/InstallVersionsTest.java | 203 - .../installer/commands/InstallerTest.java | 1036 -- .../commands/LicensePresenterTest.java | 413 - .../installer/commands/ListTest.java | 286 - .../installer/commands/MockStorage.java | 156 - .../installer/commands/UninstallTest.java | 245 - .../installer/commands/UpgradeTest.java | 699 -- .../commands/availablePrintAll.golden | 8 - .../component/installer/commands/catalog | 12 - .../component/installer/commands/catalog.rcb1 | 45 - .../commands/catalogInstallTest.properties | 21 - .../commands/catalogInstallTest2.properties | 21 - .../commands/catalogMultiFlavours.properties | 52 - .../commands/cataloginstallDeps.properties | 41 - .../commands/cataloginstallDeps2.properties | 37 - .../commands/data/catalog-19.3.2.properties | 77 - .../commands/data/catalog-20.3.0.properties | 11 - .../commands/data/catalog21patch.properties | 310 - .../data/graalvm-20.2-with-updates.properties | 170 - .../graalvmee-20.2-with-updates.properties | 154 - .../installer/commands/data/license.txt | 1 - .../commands/data/llvm-deps-19.3.2.jar | Bin 479 -> 0 bytes .../data/native-image-deps-19.3.2.jar | Bin 488 -> 0 bytes .../data/release21ceWithEE.properties | 15 - .../installer/commands/data/releases.json | 108 - .../installer/commands/graalvm-fastr.zip | Bin 180590 -> 0 bytes .../installer/commands/graalvm-ruby.zip | Bin 180590 -> 0 bytes .../license.python/META-INF/MANIFEST.MF | 6 - .../commands/license.python/license.txt | 1 - .../license.ruby/META-INF/MANIFEST.MF | 6 - .../jre/languages/ruby/LICENCE.md | 12 - .../license.ruby/jre/languages/ruby/README.md | 134 - .../commands/license.ruby/license.txt | 1 - .../installer/commands/llvm-deps.jar | Bin 482 -> 0 bytes .../installer/commands/native-image-deps.jar | Bin 493 -> 0 bytes .../component/installer/commands/postinst.jar | Bin 780 -> 0 bytes .../installer/commands/postinst2.jar | Bin 1237 -> 0 bytes .../component/installer/commands/r-deps.jar | Bin 485 -> 0 bytes .../graalvm/component/installer/commands/ruby | 1 - .../installer/commands/ruby-deps.jar | Bin 488 -> 0 bytes .../component/installer/commands/ruby2 | 1 - .../installer/commands/truffleruby-i386.zip | Bin 86845 -> 0 bytes .../installer/commands/truffleruby2-11.jar | Bin 86821 -> 0 bytes .../installer/commands/truffleruby2.jar | Bin 86813 -> 0 bytes .../installer/commands/truffleruby3.jar | Bin 86846 -> 0 bytes .../installer/commands/trufflerubyRO.jar | Bin 86851 -> 0 bytes .../installer/commands/trufflerubyWork.jar | Bin 87896 -> 0 bytes .../data/release21ceWithEE.properties | 26 - .../installer/gds/GraalChannelBaseTest.java | 85 - .../gds/data/catalog-19.3.2.properties | 77 - .../gds/data/catalog-20.3.0.properties | 15 - .../installer/gds/data/insttest.json | 20 - .../component/installer/gds/data/license.txt | 1 - .../installer/gds/data/llvm-deps-20.3.0.jar | Bin 478 -> 0 bytes .../gds/data/native-image-deps-20.3.0.jar | Bin 487 -> 0 bytes .../installer/gds/data/rel-badJava.json | 27 - .../installer/gds/data/rel-badVersion.json | 26 - .../gds/data/rel-invalid-catalog.json | 26 - .../gds/data/rel-missingEdition.json | 25 - .../installer/gds/data/rel-no-bases.json | 9 - .../installer/gds/data/releases-mix.json | 171 - .../installer/gds/data/releases.json | 44 - .../installer/gds/data/releases2.json | 108 - .../gds/rest/ArtifactParserTest.java | 287 - .../gds/rest/GDSCatalogStorageTest.java | 88 - .../installer/gds/rest/GDSChannelTest.java | 396 - .../installer/gds/rest/GDSFileConnector.java | 63 - .../gds/rest/GDSRESTConnectorTest.java | 424 - .../gds/rest/GDSTokenStorageTest.java | 279 - .../gds/rest/TestGDSTokenStorage.java | 71 - .../installer/gds/rest/data/gdsreleases.json | 9676 ----------------- .../installer/model/CatalogContentsTest.java | 234 - .../model/ComponentRegistryTest.java | 351 - .../model/MergedCatalogContentsTest.java | 206 - .../installer/model/VerifierTest.java | 86 - .../installer/model/catalog-deps.properties | 41 - .../installer/model/truffleruby2.jar | Bin 113113 -> 0 bytes .../installer/persist/Bundle.properties | 30 - .../persist/ComponentPackageLoaderTest.java | 390 - .../persist/DirectoryCatalogProviderTest.java | 244 - .../persist/DirectoryChannelFactoryTest.java | 92 - .../persist/DirectoryMetaLoader.java | 240 - .../persist/DirectoryStorageTest.java | 752 -- .../installer/persist/HeaderParserTest.java | 414 - .../installer/persist/NetworkTestBase.java | 33 - .../installer/persist/ProxyResource.java | 71 - .../component/installer/persist/broken1.zip | Bin 5081 -> 0 bytes .../persist/brokenChainedSymlinks.properties | 1 - .../persist/brokenPermissions.properties | 1 - .../persist/brokenSymlinks.properties | 5 - .../persist/chainedSymlinks.properties | 4 - .../persist/circularSymlinks.properties | 3 - .../component/installer/persist/data/catalog | 12 - .../installer/persist/data/core1.component | 8 - .../data/distributionTypeBundled.properties | 5 - .../data/distributionTypeInvalid.properties | 6 - .../data/distributionTypeMissing.properties | 4 - .../installer/persist/data/fastr.properties | 5 - .../installer/persist/data/licensetest.jar | Bin 8491 -> 0 bytes .../installer/persist/data/llvm-toolchain.jar | Bin 1248 -> 0 bytes .../persist/data/postinstMessage.jar | Bin 452 -> 0 bytes .../persist/data/requiredKeys.properties | 4 - .../component/installer/persist/data/ruby.jar | Bin 180618 -> 0 bytes .../stabilityLevelExperimental.properties | 6 - .../stabilityLevelExperimental2.properties | 7 - .../data/stabilityLevelNone.properties | 5 - .../data/stabilityLevelUnknown.properties | 6 - .../persist/data/stabilityNew.properties | 5 - .../persist/data/stabilityOld.properties | 5 - .../data/stabilityPrecedence.properties | 6 - .../installer/persist/data/truffleruby2.jar | Bin 180588 -> 0 bytes .../installer/persist/data/truffleruby3.jar | Bin 180589 -> 0 bytes .../data/workingDirectories.properties | 5 - .../installer/persist/dir1/invalid-bundle.zip | Bin 5087 -> 0 bytes .../installer/persist/dir1/llvm-toolchain.jar | Bin 1251 -> 0 bytes .../installer/persist/dir1/missing-bundle.zip | Bin 5088 -> 0 bytes .../persist/dir1/missing-manifest.zip | Bin 4779 -> 0 bytes .../installer/persist/dir1/ruby-11.jar | Bin 180620 -> 0 bytes .../component/installer/persist/dir1/ruby.jar | Bin 180611 -> 0 bytes .../installer/persist/emptylist/placeholder | 1 - .../persist/golden-replaced-files.properties | 1 - .../persist/golden-save-component.properties | 4 - .../persist/golden-save-component2.properties | 5 - .../persist/golden-save-filelist.properties | 2 - .../persist/golden-save-optional.properties | 4 - .../installer/persist/graalvmcore.properties | 4 - .../installer/persist/list1/fastr-2.component | 5 - .../installer/persist/list1/fastr.component | 4 - .../persist/list1/org.graalvm.fastr.filelist | 3 - .../installer/persist/list1/ruby.component | 4 - .../installer/persist/list1/sulong.component | 0 .../installer/persist/list2/fastr.component | 0 .../installer/persist/list2/fastr.filelist | 3 - .../installer/persist/list2/leftover.filelist | 0 .../installer/persist/list2/ruby.component | 0 .../installer/persist/list2/ruby.filelist | 0 .../installer/persist/list2/sulong.component | 0 .../installer/persist/list3/fastr.component | 4 - .../persist/list3/org.graalvm.fastr.filelist | 3 - .../installer/persist/list3/ruby.meta | 4 - .../persist/release_corrupted.properties | 5 - .../persist/release_ee_simple.properties | 4 - .../persist/release_noVersion.properties | 5 - .../persist/release_simple.properties | 5 - .../persist/replaced-files.properties | 2 - .../installer/persist/test/Handler.java | 129 - .../installer/persist/test/TestCatalog.java | 54 - .../installer/remote/CatalogCompatTest.java | 258 - .../installer/remote/FileDownloaderTest.java | 401 - .../remote/GraalEditionListTest.java | 302 - .../remote/ProxyConnectionFactoryTest.java | 177 - .../remote/RemoteCatalogDownloaderTest.java | 352 - .../installer/remote/RemoteStorageTest.java | 344 - .../installer/remote/catalog.bad1.properties | 11 - .../installer/remote/catalog.bad2.properties | 11 - .../installer/remote/catalog.properties | 12 - .../remote/catalogCorrupted.properties | 12 - .../remote/catalogFormat1.properties | 91 - .../remote/catalogFormat2.properties | 90 - .../remote/catalogFormatMix.properties | 135 - .../remote/catalogMultiFlavours.properties | 52 - .../remote/catalogMultiPart1.properties | 17 - .../catalogMultiPart1Mergeable.properties | 18 - .../remote/catalogMultiPart2.properties | 13 - .../remote/catalogMultiPart3.properties | 8 - .../remote/catalogMultiVersions.properties | 44 - .../catalogWithDifferentOsArch.properties | 75 - .../remote/data/emptyRelease.properties | 7 - .../remote/data/release20ce.properties | 8 - .../remote/data/release20ceWithEE.properties | 8 - .../remote/data/release20ee.properties | 10 - .../remote/data/release21ce.properties | 15 - .../remote/data/release21ceWithEE.properties | 26 - .../installer/remote/data/truffleruby2.jar | Bin 180588 -> 0 bytes .../repo/19.3.0.0/graalvm-19.3.0.0.jar | Bin 29450 -> 0 bytes .../llvm-toolchain/META-INF/MANIFEST.MF | 5 - .../llvm-toolchain/META-INF/permissions | 7 - .../19.3.0.0/llvm-toolchain/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../llvm-toolchain/jre/languages/ruby/release | 3 - .../repo/19.3.0.0/r/META-INF/MANIFEST.MF | 25 - .../repo/19.3.0.0/r/META-INF/permissions | 1622 --- .../repo/19.3.0.0/r/META-INF/symlinks | 3 - .../19.3.0.0/r/jre/languages/R/LICENSE_FASTR | 720 -- .../19.3.0.0/r/jre/languages/R/README_FASTR | 70 - .../19.3.0.0/r/jre/languages/R/doc/THANKS | 70 - .../19.3.0.0/r/jre/languages/R/include/linked | 0 .../jre/languages/R/library/utils/DESCRIPTION | 11 - .../r/jre/languages/R/native-image.properties | 28 - .../repo/19.3.0.0/r/jre/languages/R/release | 3 - .../r/jre/languages/R/share/java/README | 3 - .../repo/19.3.0.0/ruby/META-INF/MANIFEST.MF | 14 - .../repo/19.3.0.0/ruby/META-INF/permissions | 7 - .../repo/19.3.0.0/ruby/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../ruby/jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../19.3.0.0/ruby/jre/languages/ruby/release | 3 - .../installer/repo/catalog-19.3.properties | 68 - .../installer/repo/catalog.properties | 103 - .../installer/repo/catalog2.properties | 83 - .../installer/repo/core/graalvm-1.0.1.0.jar | Bin 29393 -> 0 bytes .../installer/repo/core/graalvm-1.1.0.0.jar | Bin 29374 -> 0 bytes .../installer/repo/core/graalvm-1.1.0.1.jar | Bin 29374 -> 0 bytes .../repo/core/graalvm-1.1.1-0.rc.1.jar | Bin 29378 -> 0 bytes .../1.1.0.0/META-INF/MANIFEST.MF | 13 - .../1.1.0.0/META-INF/permissions | 7 - .../llvm-toolchain/1.1.0.0/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../1.1.0.0/jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../1.1.0.0/jre/languages/ruby/release | 3 - .../repo/python/1.0.0.0/META-INF/MANIFEST.MF | 6 - .../repo/python/1.0.0.0/META-INF/permissions | 4 - .../repo/python/1.0.0.0/META-INF/symlinks | 1 - .../jre/languages/python/LICENSE_GRAALPYTHON | 76 - .../jre/languages/python/doc/INTEROP.md | 98 - .../jre/languages/python/include/boolobject.h | 39 - .../python/lib-graalpython/_descriptor.py | 96 - .../python/lib-python/3/_bootlocale.py | 85 - .../languages/python/native-image.properties | 13 - .../1.0.0.0/jre/languages/python/release | 3 - .../repo/python/1.0.1.0/META-INF/MANIFEST.MF | 6 - .../repo/python/1.0.1.0/META-INF/permissions | 4 - .../repo/python/1.0.1.0/META-INF/symlinks | 1 - .../jre/languages/python/LICENSE_GRAALPYTHON | 76 - .../jre/languages/python/doc/INTEROP.md | 98 - .../jre/languages/python/include/boolobject.h | 39 - .../python/lib-graalpython/_descriptor.py | 96 - .../python/lib-python/3/_bootlocale.py | 85 - .../languages/python/native-image.properties | 13 - .../1.0.1.0/jre/languages/python/release | 3 - .../repo/python/1.1.0.0/META-INF/MANIFEST.MF | 6 - .../repo/python/1.1.0.0/META-INF/permissions | 4 - .../repo/python/1.1.0.0/META-INF/symlinks | 1 - .../jre/languages/python/LICENSE_GRAALPYTHON | 76 - .../jre/languages/python/doc/INTEROP.md | 98 - .../jre/languages/python/include/boolobject.h | 39 - .../python/lib-graalpython/_descriptor.py | 96 - .../python/lib-python/3/_bootlocale.py | 85 - .../languages/python/native-image.properties | 13 - .../1.1.0.0/jre/languages/python/release | 3 - .../repo/r/1.0.1.0/META-INF/MANIFEST.MF | 24 - .../repo/r/1.0.1.0/META-INF/permissions | 1622 --- .../repo/r/1.0.1.0/META-INF/symlinks | 3 - .../r/1.0.1.0/jre/languages/R/LICENSE_FASTR | 720 -- .../r/1.0.1.0/jre/languages/R/README_FASTR | 70 - .../repo/r/1.0.1.0/jre/languages/R/doc/THANKS | 70 - .../r/1.0.1.0/jre/languages/R/include/linked | 0 .../jre/languages/R/library/utils/DESCRIPTION | 11 - .../jre/languages/R/native-image.properties | 28 - .../repo/r/1.0.1.0/jre/languages/R/release | 3 - .../1.0.1.0/jre/languages/R/share/java/README | 3 - .../repo/r/1.1.0.0/META-INF/MANIFEST.MF | 24 - .../repo/r/1.1.0.0/META-INF/permissions | 1622 --- .../repo/r/1.1.0.0/META-INF/symlinks | 3 - .../r/1.1.0.0/jre/languages/R/LICENSE_FASTR | 720 -- .../r/1.1.0.0/jre/languages/R/README_FASTR | 70 - .../repo/r/1.1.0.0/jre/languages/R/doc/THANKS | 70 - .../r/1.1.0.0/jre/languages/R/include/linked | 0 .../jre/languages/R/library/utils/DESCRIPTION | 11 - .../jre/languages/R/native-image.properties | 28 - .../repo/r/1.1.0.0/jre/languages/R/release | 3 - .../1.1.0.0/jre/languages/R/share/java/README | 3 - .../repo/ruby/1.0.1.0/META-INF/MANIFEST.MF | 13 - .../repo/ruby/1.0.1.0/META-INF/permissions | 7 - .../repo/ruby/1.0.1.0/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../ruby/1.0.1.0/jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../ruby/1.0.1.0/jre/languages/ruby/release | 3 - .../repo/ruby/1.0.1.1/META-INF/MANIFEST.MF | 13 - .../repo/ruby/1.0.1.1/META-INF/permissions | 7 - .../repo/ruby/1.0.1.1/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../ruby/1.0.1.1/jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../ruby/1.0.1.1/jre/languages/ruby/release | 3 - .../repo/ruby/1.1.0.0/META-INF/MANIFEST.MF | 13 - .../repo/ruby/1.1.0.0/META-INF/permissions | 7 - .../repo/ruby/1.1.0.0/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../ruby/1.1.0.0/jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../ruby/1.1.0.0/jre/languages/ruby/release | 3 - .../repo/ruby/1.1.0_1.0/META-INF/MANIFEST.MF | 13 - .../repo/ruby/1.1.0_1.0/META-INF/permissions | 7 - .../repo/ruby/1.1.0_1.0/META-INF/symlinks | 6 - .../jre/languages/ruby/LICENSE_TRUFFLERUBY.md | 1 - .../1.1.0_1.0/jre/languages/ruby/README.md | 218 - .../ruby/doc/doc/legal/ruby-licence.txt | 56 - .../languages/ruby/doc/doc/user/netbeans.md | 29 - .../languages/ruby/native-image.properties | 15 - .../ruby/1.1.0_1.0/jre/languages/ruby/release | 3 - .../graalvm/component/installer/repo/versions | 12 - .../installer/native-image.properties | 3 - .../installer/resource-config.json | 14 - ...component.installer.ComponentArchiveReader | 1 - ...omponent.installer.SoftwareChannel$Factory | 3 - .../component/installer/AbstractIterable.java | 157 - .../graalvm/component/installer/Archive.java | 117 - .../component/installer/Bundle.properties | 139 - .../component/installer/BundleConstants.java | 83 - .../component/installer/CommandInput.java | 153 - .../graalvm/component/installer/Commands.java | 264 - .../component/installer/CommonConstants.java | 190 - .../installer/ComponentArchiveReader.java | 51 - .../component/installer/ComponentCatalog.java | 93 - .../installer/ComponentCollection.java | 55 - .../installer/ComponentInstaller.java | 929 -- .../installer/ComponentIterable.java | 38 - .../component/installer/ComponentParam.java | 46 - .../graalvm/component/installer/Config.java | 48 - .../installer/DependencyException.java | 100 - .../installer/DownloadURLIterable.java | 100 - .../component/installer/Environment.java | 639 -- .../installer/FailedOperationException.java | 44 - .../graalvm/component/installer/Feedback.java | 206 - .../component/installer/FileIterable.java | 159 - .../component/installer/FileOperations.java | 180 - .../component/installer/GenerateCatalog.java | 478 - .../installer/IncompatibleException.java | 41 - .../component/installer/InstallerCommand.java | 58 - .../installer/InstallerStopException.java | 43 - .../installer/MetadataException.java | 42 - .../installer/NonInteractiveException.java | 38 - .../component/installer/SimpleGetopt.java | 366 - .../component/installer/SoftwareChannel.java | 102 - .../installer/SoftwareChannelSource.java | 90 - .../installer/SuppressFBWarnings.java | 42 - .../component/installer/SystemUtils.java | 899 -- .../installer/URLConnectionFactory.java | 43 - .../installer/UnknownVersionException.java | 50 - .../installer/UserAbortException.java | 41 - .../graalvm/component/installer/Version.java | 740 -- .../component/installer/ce/Bundle.properties | 23 - .../installer/ce/JarPackageProvider.java | 64 - .../component/installer/ce/WebCatalog.java | 324 - .../installer/commands/AbstractInstaller.java | 227 - .../installer/commands/AvailableCommand.java | 180 - .../installer/commands/Bundle.properties | 409 - .../installer/commands/GraalVMInstaller.java | 250 - .../installer/commands/InfoCommand.java | 341 - .../installer/commands/InstallCommand.java | 804 -- .../installer/commands/Installer.java | 460 - .../installer/commands/LicensePresenter.java | 414 - .../commands/ListInstalledCommand.java | 167 - .../installer/commands/PostInstCommand.java | 68 - .../installer/commands/PostInstProcess.java | 117 - .../installer/commands/PreRemoveCommand.java | 68 - .../installer/commands/PreRemoveProcess.java | 168 - .../installer/commands/QueryCommandBase.java | 294 - .../commands/RebuildImageCommand.java | 160 - .../installer/commands/UninstallCommand.java | 315 - .../installer/commands/Uninstaller.java | 155 - .../installer/commands/UpgradeCommand.java | 181 - .../installer/commands/UpgradeProcess.java | 777 -- .../component/installer/gds/Bundle.properties | 10 - .../component/installer/gds/GdsCommands.java | 45 - .../installer/gds/GraalChannelBase.java | 226 - .../component/installer/gds/MailStorage.java | 149 - .../installer/gds/rest/ArtifactParser.java | 263 - .../installer/gds/rest/Bundle.properties | 66 - .../installer/gds/rest/GDSCatalogStorage.java | 73 - .../installer/gds/rest/GDSChannel.java | 337 - .../installer/gds/rest/GDSChannelFactory.java | 109 - .../installer/gds/rest/GDSRESTConnector.java | 398 - .../installer/gds/rest/GDSTokenStorage.java | 291 - .../component/installer/jar/Bundle.properties | 5 - .../component/installer/jar/JarArchive.java | 153 - .../installer/jar/JarMetaLoader.java | 175 - .../installer/model/Bundle.properties | 6 - .../installer/model/CatalogContents.java | 397 - .../installer/model/ComponentInfo.java | 492 - .../installer/model/ComponentRegistry.java | 579 - .../installer/model/ComponentStorage.java | 63 - .../installer/model/DistributionType.java | 44 - .../installer/model/GraalEdition.java | 110 - .../installer/model/ManagementStorage.java | 79 - .../installer/model/RemoteInfoProcessor.java | 41 - .../installer/model/StabilityLevel.java | 82 - .../component/installer/model/Verifier.java | 263 - .../component/installer/os/Bundle.properties | 5 - .../installer/os/DefaultFileOperations.java | 95 - .../installer/os/WindowsFileOperations.java | 262 - .../installer/os/WindowsJVMWrapper.java | 183 - .../persist/AbstractCatalogStorage.java | 73 - .../installer/persist/Bundle.properties | 55 - .../persist/ComponentPackageLoader.java | 504 - .../persist/DirectoryCatalogProvider.java | 188 - .../persist/DirectoryChannelFactory.java | 72 - .../installer/persist/DirectoryStorage.java | 819 -- .../installer/persist/HeaderParser.java | 656 -- .../installer/persist/MetadataLoader.java | 121 - .../persist/MetadataLoaderAdapter.java | 132 - .../installer/persist/SortedProperties.java | 69 - .../installer/remote/Bundle.properties | 72 - .../installer/remote/CatalogIterable.java | 330 - .../installer/remote/FileDownloader.java | 448 - .../installer/remote/GraalEditionList.java | 588 - .../installer/remote/MergeStorage.java | 197 - .../remote/ProxyConnectionFactory.java | 552 - .../remote/RemoteCatalogDownloader.java | 256 - .../remote/RemoteComponentParam.java | 425 - .../remote/RemotePropertiesStorage.java | 256 - 449 files changed, 41 insertions(+), 64165 deletions(-) delete mode 100755 vm/mx.vm/gu-deprecated delete mode 100755 vm/mx.vm/gu-deprecated.cmd delete mode 100644 vm/mx.vm/gu.cmd delete mode 100644 vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader delete mode 100644 vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CatalogIterableTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ChunkedConnection.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CommandTestBase.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ComponentInstallerTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DirectoryArchiveReader.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DownloadURLIterableTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/EnvironmentTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/InstallerCommandlineTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MemoryFeedback.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MockURLConnection.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SimpleGetoptTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SystemUtilsTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/TestBase.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/VersionTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/AvailableTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/BlockedFileOps.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/CatalogInstallTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InfoTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallVersionsTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallerTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/LicensePresenterTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ListTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/MockStorage.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UninstallTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UpgradeTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/availablePrintAll.golden delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog.rcb1 delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogMultiFlavours.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-19.3.2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-20.3.0.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog21patch.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvm-20.2-with-updates.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvmee-20.2-with-updates.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/license.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/llvm-deps-19.3.2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/native-image-deps-19.3.2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/release21ceWithEE.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/releases.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/graalvm-fastr.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/graalvm-ruby.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/license.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/LICENCE.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/license.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/llvm-deps.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/native-image-deps.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/postinst.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/postinst2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/r-deps.jar delete mode 100755 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ruby delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ruby-deps.jar delete mode 100755 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ruby2 delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/truffleruby-i386.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/truffleruby2-11.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/truffleruby2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/truffleruby3.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/trufflerubyRO.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/trufflerubyWork.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/data/release21ceWithEE.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/GraalChannelBaseTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-19.3.2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-20.3.0.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/insttest.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/license.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/llvm-deps-20.3.0.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/native-image-deps-20.3.0.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badJava.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badVersion.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-invalid-catalog.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-missingEdition.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-no-bases.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases-mix.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases2.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/ArtifactParserTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorageTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSChannelTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSFileConnector.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSRESTConnectorTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSTokenStorageTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/TestGDSTokenStorage.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/data/gdsreleases.json delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/CatalogContentsTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/ComponentRegistryTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/MergedCatalogContentsTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/VerifierTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/catalog-deps.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/truffleruby2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ComponentPackageLoaderTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryCatalogProviderTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryChannelFactoryTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryMetaLoader.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryStorageTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/HeaderParserTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/NetworkTestBase.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ProxyResource.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/broken1.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenChainedSymlinks.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenPermissions.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenSymlinks.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/chainedSymlinks.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/circularSymlinks.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/catalog delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/core1.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeBundled.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeInvalid.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeMissing.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/fastr.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/licensetest.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/llvm-toolchain.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/postinstMessage.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/requiredKeys.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/ruby.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityLevelExperimental.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityLevelExperimental2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityLevelNone.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityLevelUnknown.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityNew.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityOld.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/stabilityPrecedence.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/truffleruby2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/truffleruby3.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/workingDirectories.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/invalid-bundle.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/llvm-toolchain.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/missing-bundle.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/missing-manifest.zip delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/ruby-11.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/ruby.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/emptylist/placeholder delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-replaced-files.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-filelist.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-optional.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/graalvmcore.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr-2.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/org.graalvm.fastr.filelist delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/ruby.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/sulong.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.filelist delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/leftover.filelist delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/ruby.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/ruby.filelist delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/sulong.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/fastr.component delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/org.graalvm.fastr.filelist delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/ruby.meta delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_corrupted.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_ee_simple.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_noVersion.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_simple.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/replaced-files.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/Handler.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/TestCatalog.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/CatalogCompatTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/FileDownloaderTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/GraalEditionListTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/ProxyConnectionFactoryTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteCatalogDownloaderTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteStorageTest.java delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad1.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogCorrupted.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat1.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormatMix.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiFlavours.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1Mergeable.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart3.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiVersions.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogWithDifferentOsArch.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/emptyRelease.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ce.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ceWithEE.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ee.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ce.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ceWithEE.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/truffleruby2.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/graalvm-19.3.0.0.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/LICENSE_FASTR delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/README_FASTR delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/doc/THANKS delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/include/linked delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/library/utils/DESCRIPTION delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/share/java/README delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog-19.3.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog2.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.0.1.0.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.1.0.0.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.1.0.1.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.1.1-0.rc.1.jar delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/LICENSE_GRAALPYTHON delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/doc/INTEROP.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/include/boolobject.h delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-graalpython/_descriptor.py delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-python/3/_bootlocale.py delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/LICENSE_GRAALPYTHON delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/doc/INTEROP.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/include/boolobject.h delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-graalpython/_descriptor.py delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-python/3/_bootlocale.py delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/LICENSE_GRAALPYTHON delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/doc/INTEROP.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/include/boolobject.h delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-graalpython/_descriptor.py delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-python/3/_bootlocale.py delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/LICENSE_FASTR delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/README_FASTR delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/doc/THANKS delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/include/linked delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/library/utils/DESCRIPTION delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/share/java/README delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/LICENSE_FASTR delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/README_FASTR delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/doc/THANKS delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/include/linked delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/library/utils/DESCRIPTION delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/share/java/README delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/MANIFEST.MF delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/permissions delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/symlinks delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/README.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/user/netbeans.md delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/release delete mode 100644 vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/versions delete mode 100644 vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/native-image.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/resource-config.json delete mode 100644 vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader delete mode 100644 vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/AbstractIterable.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Archive.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/BundleConstants.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommandInput.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Commands.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommonConstants.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentArchiveReader.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCatalog.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCollection.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentInstaller.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentIterable.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentParam.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Config.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DependencyException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DownloadURLIterable.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Environment.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FailedOperationException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Feedback.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileIterable.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileOperations.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/GenerateCatalog.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/IncompatibleException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerStopException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/MetadataException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/NonInteractiveException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SimpleGetopt.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannel.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannelSource.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SuppressFBWarnings.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SystemUtils.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/URLConnectionFactory.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UnknownVersionException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UserAbortException.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Version.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/JarPackageProvider.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/WebCatalog.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AbstractInstaller.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AvailableCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/GraalVMInstaller.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InfoCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InstallCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Installer.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/LicensePresenter.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/ListInstalledCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstProcess.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveProcess.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/QueryCommandBase.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/RebuildImageCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UninstallCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Uninstaller.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeCommand.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeProcess.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GdsCommands.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GraalChannelBase.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/MailStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/ArtifactParser.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannel.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannelFactory.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSRESTConnector.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSTokenStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarArchive.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarMetaLoader.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/CatalogContents.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentInfo.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentRegistry.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/DistributionType.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/GraalEdition.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ManagementStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/RemoteInfoProcessor.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/StabilityLevel.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Verifier.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/DefaultFileOperations.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsFileOperations.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsJVMWrapper.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/AbstractCatalogStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/ComponentPackageLoader.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryCatalogProvider.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryChannelFactory.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/HeaderParser.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoader.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoaderAdapter.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/SortedProperties.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/Bundle.properties delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/CatalogIterable.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/FileDownloader.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/GraalEditionList.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/MergeStorage.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/ProxyConnectionFactory.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteCatalogDownloader.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteComponentParam.java delete mode 100644 vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemotePropertiesStorage.java diff --git a/sdk/mx.sdk/mx_sdk_vm_impl.py b/sdk/mx.sdk/mx_sdk_vm_impl.py index 4df39802976e..54047c179792 100644 --- a/sdk/mx.sdk/mx_sdk_vm_impl.py +++ b/sdk/mx.sdk/mx_sdk_vm_impl.py @@ -765,28 +765,6 @@ def _add_link(_dest, _target, _component=None, _dest_base_name=None): graalvm_dists.difference_update(component_dists) _add(layout, '/lib/graalvm/', ['dependency:' + d for d in sorted(graalvm_dists)], with_sources=True) - if mx.suite('vm', fatalIfMissing=False): - import mx_vm - installer_components_dir = _get_component_type_base(mx_vm.gu_component) + mx_vm.gu_component.dir_name + '/components/' - if not is_graalvm or get_component(mx_vm.gu_component.short_name, stage1=stage1): - # Execute the following code if this is not a GraalVM distribution (e.g., is an installable) or if the - # GraalVM distribution includes `gu`. - # - # Register pre-installed components - for installable_components in installable_component_lists.values(): - manifest_str = _gen_gu_manifest(installable_components, _format_properties, bundled=True) - main_component = _get_main_component(installable_components) - mx.logv("Adding gu metadata for{}installable '{}'".format(' disabled ' if _disable_installable(main_component) else ' ', main_component.installable_id)) - _add(layout, installer_components_dir + 'org.graalvm.' + main_component.installable_id + '.component', "string:" + manifest_str) - # Register Core - manifest_str = _format_properties({ - "Bundle-Name": "GraalVM Core", - "Bundle-Symbolic-Name": "org.graalvm", - "Bundle-Version": _suite.release_version(), - "x-GraalVM-Stability-Level": _get_core_stability(), - }) - _add(layout, installer_components_dir + 'org.graalvm.component', "string:" + manifest_str) - for _base, _suites in component_suites.items(): _metadata = self._get_metadata(_suites) _add(layout, _base + 'release', "string:{}".format(_metadata)) @@ -857,26 +835,6 @@ def _get_metadata(suites, parent_release_file=None): _source += ' '.join(['{}:{}'.format(_s.name, _s.version()) for _s in suites]) _metadata_dict['SOURCE'] = _source _metadata_dict['COMMIT_INFO'] = json.dumps(_commit_info, sort_keys=True) - if _suite.is_release(): - catalog = _release_catalog() - gds_product_id = _release_product_id() - else: - snapshot_catalog = _snapshot_catalog() - gds_product_id = _snapshot_product_id() - gds_snapshot_catalog = _gds_snapshot_catalog() - if snapshot_catalog and _suite.vc: - catalog = "{}/{}".format(snapshot_catalog, _suite.vc.parent(_suite.vc_dir)) - if gds_snapshot_catalog: - catalog += "|" + gds_snapshot_catalog - elif gds_snapshot_catalog: - catalog = gds_snapshot_catalog - else: - catalog = None - if USE_LEGACY_GU: - if catalog: - _metadata_dict['component_catalog'] = catalog - if gds_product_id: - _metadata_dict['GDS_PRODUCT_ID'] = gds_product_id # COMMIT_INFO is unquoted to simplify JSON parsing return mx_sdk_vm.format_release_file(_metadata_dict, {'COMMIT_INFO'}) @@ -2624,148 +2582,6 @@ def _gen_gu_manifest(components, formatter, bundled=False): return formatter(manifest) -class InstallableComponentArchiver(mx.Archiver): - def __init__(self, path, components, **kw_args): - """ - :type path: str - :type components: list[mx_sdk.GraalVmLanguage] - :type kind: str - :type reset_user_group: bool - :type duplicates_action: str - :type context: object - """ - super(InstallableComponentArchiver, self).__init__(path, **kw_args) - self.components = components - self.permissions = [] - self.symlinks = [] - - @staticmethod - def _perm_str(filename): - _perm = str(oct(os.lstat(filename).st_mode)[-3:]) - _str = '' - for _p in _perm: - if _p == '7': - _str += 'rwx' - elif _p == '6': - _str += 'rw-' - elif _p == '5': - _str += 'r-x' - elif _p == '4': - _str += 'r--' - elif _p == '0': - _str += '---' - else: - mx.abort('File {} has unsupported permission {}'.format(filename, _perm)) - return _str - - def add(self, filename, archive_name, provenance): - self.permissions.append('{} = {}'.format(archive_name, self._perm_str(filename))) - super(InstallableComponentArchiver, self).add(filename, archive_name, provenance) - - def add_str(self, data, archive_name, provenance): - self.permissions.append('{} = {}'.format(archive_name, 'rw-rw-r--')) - super(InstallableComponentArchiver, self).add_str(data, archive_name, provenance) - - def add_link(self, target, archive_name, provenance): - self.permissions.append('{} = {}'.format(archive_name, 'rwxrwxrwx')) - self.symlinks.append('{} = {}'.format(archive_name, target)) - # do not add symlinks, use the metadata to create them - - def __exit__(self, exc_type, exc_value, traceback): - assert self.components[0] == _get_main_component(self.components) - _manifest_str_wrapped = _gen_gu_manifest(self.components, _format_manifest) - _manifest_arc_name = 'META-INF/MANIFEST.MF' - - _permissions_str = '\n'.join(self.permissions) - _permissions_arc_name = 'META-INF/permissions' - - _symlinks_str = '\n'.join(self.symlinks) - _symlinks_arc_name = 'META-INF/symlinks' - - for _str, _arc_name in [(_manifest_str_wrapped, _manifest_arc_name), (_permissions_str, _permissions_arc_name), - (_symlinks_str, _symlinks_arc_name)]: - self.add_str(_str, _arc_name, '{}<-string:{}'.format(_arc_name, _str)) - - super(InstallableComponentArchiver, self).__exit__(exc_type, exc_value, traceback) - - -class GraalVmInstallableComponent(BaseGraalVmLayoutDistribution, mx.LayoutJARDistribution): # pylint: disable=R0901 - def __init__(self, component, extra_components=None, **kw_args): - """ - :type component: mx_sdk.GraalVmComponent - """ - self.main_component = component - - def create_archive(path, **_kw_args): - return InstallableComponentArchiver(path, self.components, **_kw_args) - - launcher_configs = list(_get_launcher_configs(component)) - for component_ in extra_components: - launcher_configs += _get_launcher_configs(component_) - - library_configs = list(_get_library_configs(component)) - for component_ in extra_components: - library_configs += _get_library_configs(component_) - - extra_installable_qualifiers = list(component.extra_installable_qualifiers) - for component_ in extra_components: - extra_installable_qualifiers += component_.extra_installable_qualifiers - - other_involved_components = [] - if self.main_component.short_name not in ('svm', 'svmee') \ - and _get_svm_support().is_supported() \ - and ( - any(not _force_bash_launchers(lc) for lc in launcher_configs) or - any(not _skip_libraries(lc) for lc in library_configs)): - other_involved_components += [c for c in registered_graalvm_components(stage1=True) if c.short_name in ('svm', 'svmee')] - - name = '{}_INSTALLABLE'.format(component.installable_id.replace('-', '_').upper()) - for library_config in library_configs: - if _skip_libraries(library_config): - name += '_S' + basename(library_config.destination).upper() - if other_involved_components: - extra_installable_qualifiers += [c.short_name for c in other_involved_components] - if not extra_installable_qualifiers: - extra_installable_qualifiers = mx_sdk_vm.extra_installable_qualifiers(mx_sdk_vm.base_jdk().home, ['ce'], None) - if extra_installable_qualifiers: - name += '_' + '_'.join(sorted(q.upper() for q in extra_installable_qualifiers)) - name += '_JAVA{}'.format(_src_jdk_version) - - for component_ in [component] + extra_components: - for boot_jar in component_.boot_jars: - mx.warn("Component '{}' declares '{}' as 'boot_jar', which is ignored by the build process of the '{}' installable".format(component_.name, boot_jar, name)) - - self.maven = _graalvm_maven_attributes(tag='installable') - components = [component] - if extra_components: - components += extra_components - super(GraalVmInstallableComponent, self).__init__( - suite=_suite, - name=name, - deps=[], - components=components, - is_graalvm=False, - exclLibs=[], - platformDependent=True, - theLicense=None, - testDistribution=False, - archive_factory=create_archive, - path=None, - include_native_image_resources_filelists=True, - **kw_args) - - def get_artifact_metadata(self): - meta = super(GraalVmInstallableComponent, self).get_artifact_metadata() - meta.update({ - 'type': 'installable', - 'installableName': self.main_component.installable_id.lower().replace('-', '_'), - 'longName': self.main_component.name, - 'stability': self.main_component.stability, - 'symbolicName': 'org.graalvm.{}'.format(self.main_component.installable_id), - }) - return meta - - class GraalVmStandaloneComponent(LayoutSuper): # pylint: disable=R0901 def __init__(self, main_component, graalvm, is_jvm, **kw_args): """ @@ -3582,7 +3398,6 @@ def _release_version(): )) main_dists = { 'graalvm': [], - 'graalvm_installables': [], 'graalvm_standalones': [], } with_non_rebuildable_configs = False @@ -3699,12 +3514,6 @@ def register_main_dist(dist, label): # Register main distribution register_main_dist(_final_graalvm_distribution, 'graalvm') - # Register installables - for components in installables.values(): - main_component = _get_main_component(components) - installable_component = GraalVmInstallableComponent(main_component, extra_components=[c for c in components if c != main_component]) - register_main_dist(installable_component, 'graalvm_installables') - # Register standalones needs_java_standalone_jimage = False for components in installables.values(): @@ -3808,7 +3617,7 @@ def register_main_dist(dist, label): jimage_project=final_jimage_project, )) - # Trivial distributions to trigger the build of the final GraalVM distribution, installables, and standalones + # Trivial distributions to trigger the build of the final GraalVM distribution and standalones all_main_dists = [] for label, dists in main_dists.items(): if dists: @@ -4287,7 +4096,7 @@ def graalvm_show(args, forced_graalvm_dist=None): if forced_graalvm_dist is None: # Custom GraalVM distributions with a forced component list do not yet support launchers and libraries. - # No installable or standalone is derived from them. + # No standalone is derived from them. launchers = [p for p in _suite.projects if isinstance(p, GraalVmLauncher) and p.get_containing_graalvm() == graalvm_dist] if launchers: print("Launchers:") @@ -4327,17 +4136,6 @@ def graalvm_show(args, forced_graalvm_dist=None): else: print("No library") - installables = _get_dists(GraalVmInstallableComponent) - if installables and not args.stage1: - print("Installables:") - for i in sorted(installables): - print(" - {}".format(i)) - if args.verbose: - for c in i.components: - print(" - {}".format(c.name)) - else: - print("No installable") - if not args.stage1: jvm_standalones = [] native_standalones = [] @@ -4383,7 +4181,7 @@ def graalvm_show(args, forced_graalvm_dist=None): for config in cfg['configs']: print(f" {config} (from {cfg['source']})") if args.verbose: - for dist_name in 'GRAALVM', 'GRAALVM_INSTALLABLES', 'GRAALVM_STANDALONES', 'ALL_GRAALVM_ARTIFACTS': + for dist_name in 'GRAALVM', 'GRAALVM_STANDALONES', 'ALL_GRAALVM_ARTIFACTS': dist = mx.distribution(dist_name, fatalIfMissing=False) if dist is not None: print(f"Dependencies of the '{dist_name}' distribution:\n -", '\n - '.join(sorted(dep.name for dep in dist.deps))) @@ -4517,11 +4315,6 @@ def graalvm_vendor_version(): mx.add_argument('--debuginfo-dists', action='store_true', help='Generate debuginfo distributions.') mx.add_argument('--generate-debuginfo', action='store', help='Comma-separated list of launchers and libraries (syntax: lib:polyglot) for which to generate debug information (`native-image -g`) (all by default)', default=None) mx.add_argument('--disable-debuginfo-stripping', action='store_true', help='Disable the stripping of debug symbols from the native image.') -mx.add_argument('--snapshot-catalog', action='store', help='Change the default URL of the component catalog for snapshots.', default=None) -mx.add_argument('--gds-snapshot-catalog', action='store', help='Change the default appended URL of the component catalog for snapshots.', default=None) -mx.add_argument('--release-catalog', action='store', help='Change the default URL of the component catalog for releases.', default=None) -mx.add_argument('--snapshot-product-id', action='store', help='Change the default ID of the GDS product ID for snapshots.', default=None) -mx.add_argument('--release-product-id', action='store', help='Change the default ID of the GDS product ID for releases.', default=None) mx.add_argument('--extra-image-builder-argument', action='append', help='Add extra arguments to the image builder.', default=[]) mx.add_argument('--image-profile', action='append', help='Add a profile to be used while building a native image.', default=[]) mx.add_argument('--no-licenses', action='store_true', help='Do not add license files in the archives.') @@ -4877,26 +4670,6 @@ def _rebuildable_image(image_config): return name not in non_rebuildable -def _snapshot_catalog(): - return mx.get_opts().snapshot_catalog or mx.get_env('SNAPSHOT_CATALOG') - - -def _gds_snapshot_catalog(): - return mx.get_opts().gds_snapshot_catalog or mx.get_env('GDS_SNAPSHOT_CATALOG') - - -def _snapshot_product_id(): - return mx.get_opts().snapshot_product_id or mx.get_env('SNAPSHOT_PRODUCT_ID') - - -def _release_catalog(): - return mx.get_opts().release_catalog or mx.get_env('RELEASE_CATALOG') - - -def _release_product_id(): - return mx.get_opts().release_product_id or mx.get_env('RELEASE_PRODUCT_ID') - - def _base_jdk_info(): base_jdk_info = mx.get_opts().base_jdk_info or mx.get_env('BASE_JDK_INFO') if base_jdk_info is None: diff --git a/vm/ci/ci_common/common.jsonnet b/vm/ci/ci_common/common.jsonnet index 1140e87400af..fd31a877ac8c 100644 --- a/vm/ci/ci_common/common.jsonnet +++ b/vm/ci/ci_common/common.jsonnet @@ -205,7 +205,7 @@ local devkits = graal_common.devkits; mx_vm_cmd_suffix: ['--sources=sdk:GRAAL_SDK,truffle:TRUFFLE_API,compiler:GRAAL,substratevm:SVM', '--debuginfo-dists', '--base-jdk-info=${BASE_JDK_NAME}:${BASE_JDK_VERSION}'], mx_vm_common: vm.mx_cmd_base_no_env + ['--env', '${VM_ENV}'] + self.mx_vm_cmd_suffix, - mx_vm_installables: vm.mx_cmd_base_no_env + ['--env', '${VM_ENV}-complete'] + self.mx_vm_cmd_suffix, + mx_vm_complete: vm.mx_cmd_base_no_env + ['--env', '${VM_ENV}-complete'] + self.mx_vm_cmd_suffix, svm_common_linux_amd64: graal_common.deps.svm, svm_common_linux_aarch64: graal_common.deps.svm, @@ -225,13 +225,16 @@ local devkits = graal_common.devkits; deploy_sdk_base_dry_run(os, base_dist_name=null): [self.mx_vm_common + vm.vm_profiles + self.maven_deploy_sdk_base_dry_run, self.mx_vm_common + vm.vm_profiles + self.artifact_deploy_sdk_base_dry_run(os, base_dist_name)], deploy_sdk_components(os, tags): [ - $.mx_vm_installables + self.maven_deploy_sdk + ['--tags', tags, vm.binaries_repository], - $.mx_vm_installables + self.deploy_artifacts_sdk(os) + ['--tags', tags] + $.mx_vm_complete + self.maven_deploy_sdk + ['--tags', tags, vm.binaries_repository], + $.mx_vm_complete + self.deploy_artifacts_sdk(os) + ['--tags', tags] ], - maven_deploy_sdk_components_dry_run: self.maven_deploy_sdk + ['--tags', 'installable,standalone', '--dry-run', vm.binaries_repository], - artifact_deploy_sdk_components_dry_run(os): self.deploy_artifacts_sdk(os) + ['--tags', 'installable,standalone', '--dry-run'], - deploy_sdk_components_dry_run(os): [$.mx_vm_installables + self.maven_deploy_sdk_components_dry_run, $.mx_vm_installables + self.artifact_deploy_sdk_components_dry_run(os)], + maven_deploy_sdk_components_dry_run: self.maven_deploy_sdk + ['--tags', 'standalone', '--dry-run', vm.binaries_repository], + artifact_deploy_sdk_components_dry_run(os): self.deploy_artifacts_sdk(os) + ['--tags', 'standalone', '--dry-run'], + deploy_sdk_components_dry_run(os): [ + $.mx_vm_complete + self.maven_deploy_sdk_components_dry_run, + $.mx_vm_complete + self.artifact_deploy_sdk_components_dry_run(os) + ], ruby_vm_build_linux_amd64: self.svm_common_linux_amd64 + self.sulong_linux + self.truffleruby_linux_amd64 + vm.custom_vm_linux, ruby_vm_build_linux_aarch64: self.svm_common_linux_aarch64 + self.sulong_linux + self.truffleruby_linux_aarch64 + vm.custom_vm_linux, @@ -589,26 +592,24 @@ local devkits = graal_common.devkits; timelimit: "1:00:00" }, - deploy_graalvm_components(java_version, installables, standalones, record_file_sizes=false): vm.check_structure + { + deploy_graalvm_components(java_version, standalones, record_file_sizes=false): vm.check_structure + { build_deps:: std.join(',', [] + (if (record_file_sizes) then ['GRAALVM'] else []) - + (if (installables) then ['GRAALVM_INSTALLABLES'] else []) + (if (standalones) then ['GRAALVM_STANDALONES'] else []) ), tags:: std.join(',', [] - + (if (installables) then ['installable'] else []) + (if (standalones) then ['standalone'] else []) ), run: $.patch_env(self.os, self.arch, java_version) + [ - $.mx_vm_installables + ['graalvm-show'], - $.mx_vm_installables + ['build', '--dependencies', self.build_deps], + $.mx_vm_complete + ['graalvm-show'], + $.mx_vm_complete + ['build', '--dependencies', self.build_deps], ] + $.deploy_sdk_components(self.os, self.tags) + ( if (record_file_sizes) then [ - $.mx_vm_installables + $.record_file_sizes, + $.mx_vm_complete + $.record_file_sizes, $.upload_file_sizes, ] else [] ), @@ -633,52 +634,49 @@ local devkits = graal_common.devkits; }, # - # Deploy GraalVM Base and Installables + # Deploy GraalVM Base and Standalones # NOTE: After adding or removing deploy jobs, please make sure you modify ce-release-artifacts.json accordingly. # # Linux/AMD64 # - JDK-Latest deploy_vm_base_javaLatest_linux_amd64: vm.vm_java_Latest + self.full_vm_build_linux_amd64 + self.linux_deploy + self.vm_base('linux', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_base('latest') + {name: 'post-merge-deploy-vm-base-java-latest-linux-amd64', notify_groups:: ["deploy"]}, - deploy_vm_installables_standalones_javaLatest_linux_amd64: vm.vm_java_Latest + self.full_vm_build_linux_amd64 + self.linux_deploy + self.vm_base('linux', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components('latest', installables=false, standalones=true, record_file_sizes=true) + {name: 'post-merge-deploy-vm-installables-standalones-java-latest-linux-amd64', notify_groups:: ["deploy"]}, + deploy_vm_standalones_javaLatest_linux_amd64: vm.vm_java_Latest + self.full_vm_build_linux_amd64 + self.linux_deploy + self.vm_base('linux', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components('latest', standalones=true, record_file_sizes=true) + {name: 'post-merge-deploy-vm-standalones-java-latest-linux-amd64', notify_groups:: ["deploy"]}, # - JDK21 deploy_vm_base_java21_linux_amd64: vm.vm_java_21 + self.full_vm_build_linux_amd64 + self.linux_deploy + self.vm_base('linux', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_base("java21") + {name: 'post-merge-deploy-vm-base-java21-linux-amd64', notify_groups:: ["deploy"]}, - deploy_vm_installables_standalones_java21_linux_amd64: vm.vm_java_21_llvm + self.full_vm_build_linux_amd64 + self.linux_deploy + self.vm_base('linux', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", installables=true, standalones=true, record_file_sizes=true) + {name: 'post-merge-deploy-vm-installables-standalones-java21-linux-amd64', notify_groups:: ["deploy"]}, + deploy_vm_standalones_java21_linux_amd64: vm.vm_java_21_llvm + self.full_vm_build_linux_amd64 + self.linux_deploy + self.vm_base('linux', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", standalones=true, record_file_sizes=true) + {name: 'post-merge-deploy-vm-standalones-java21-linux-amd64', notify_groups:: ["deploy"]}, # Linux/AARCH64 # - JDK-Latest deploy_vm_base_javaLatest_linux_aarch64: vm.vm_java_Latest + self.full_vm_build_linux_aarch64 + self.linux_deploy + self.vm_base('linux', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_base('latest') + {name: 'post-merge-deploy-vm-base-java-latest-linux-aarch64', notify_groups:: ["deploy"], timelimit: '1:30:00', capabilities+: ["!xgene3"]}, - deploy_vm_installables_standalones_javaLatest_linux_aarch64: vm.vm_java_Latest + self.full_vm_build_linux_aarch64 + self.linux_deploy + self.vm_base('linux', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components('latest', installables=false, standalones=true) + {name: 'post-merge-deploy-vm-installables-standalones-java-latest-linux-aarch64', notify_groups:: ["deploy"], capabilities+: ["!xgene3"]}, + deploy_vm_standalones_javaLatest_linux_aarch64: vm.vm_java_Latest + self.full_vm_build_linux_aarch64 + self.linux_deploy + self.vm_base('linux', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components('latest', standalones=true) + {name: 'post-merge-deploy-vm-standalones-java-latest-linux-aarch64', notify_groups:: ["deploy"], capabilities+: ["!xgene3"]}, # - JDK21 deploy_vm_base_java21_linux_aarch64: vm.vm_java_21 + self.full_vm_build_linux_aarch64 + self.linux_deploy + self.vm_base('linux', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_base("java21") + {name: 'post-merge-deploy-vm-base-java21-linux-aarch64', notify_groups:: ["deploy"], timelimit: '1:30:00', capabilities+: ["!xgene3"]}, - deploy_vm_installables_standalones_java21_linux_aarch64: vm.vm_java_21 + self.full_vm_build_linux_aarch64 + self.linux_deploy + self.vm_base('linux', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", installables=true, standalones=true) + {name: 'post-merge-deploy-vm-installables-standalones-java21-linux-aarch64', notify_groups:: ["deploy"], capabilities+: ["!xgene3"]}, + deploy_vm_standalones_java21_linux_aarch64: vm.vm_java_21 + self.full_vm_build_linux_aarch64 + self.linux_deploy + self.vm_base('linux', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", standalones=true) + {name: 'post-merge-deploy-vm-standalones-java21-linux-aarch64', notify_groups:: ["deploy"], capabilities+: ["!xgene3"]}, # Darwin/AMD64 # - JDK-Latest deploy_vm_base_javaLatest_darwin_amd64: vm.vm_java_Latest + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true, jdk_hint='Latest') + self.deploy_graalvm_base('latest') + {name: 'post-merge-deploy-vm-base-java-latest-darwin-amd64', notify_groups:: ["deploy"], timelimit: '1:45:00'}, - deploy_vm_standalones_javaLatest_darwin_amd64: vm.vm_java_Latest + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true, jdk_hint='Latest') + self.deploy_graalvm_components('latest', installables=false, standalones=true) + {name: 'post-merge-deploy-vm-standalones-java-latest-darwin-amd64', capabilities+: ["!macmini_late_2014"], diskspace_required: "31GB", notify_groups:: ["deploy"], timelimit: '3:00:00'}, + deploy_vm_standalones_javaLatest_darwin_amd64: vm.vm_java_Latest + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true, jdk_hint='Latest') + self.deploy_graalvm_components('latest', standalones=true) + {name: 'post-merge-deploy-vm-standalones-java-latest-darwin-amd64', capabilities+: ["!macmini_late_2014"], diskspace_required: "31GB", notify_groups:: ["deploy"], timelimit: '3:00:00'}, # - JDK21 deploy_vm_base_java21_darwin_amd64: vm.vm_java_21 + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_base("java21") + {name: 'post-merge-deploy-vm-base-java21-darwin-amd64', notify_groups:: ["deploy"], timelimit: '1:45:00'}, - deploy_vm_installables_java21_darwin_amd64: vm.vm_java_21_llvm + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", installables=true, standalones=false) + {name: 'post-merge-deploy-vm-installables-java21-darwin-amd64', capabilities+: ["!macmini_late_2014"], diskspace_required: "31GB", notify_groups:: ["deploy"], timelimit: '3:00:00'}, - deploy_vm_standalones_java21_darwin_amd64: vm.vm_java_21_llvm + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", installables=false, standalones=true) + {name: 'post-merge-deploy-vm-standalones-java21-darwin-amd64', capabilities+: ["!macmini_late_2014"], diskspace_required: "31GB", notify_groups:: ["deploy"], timelimit: '3:00:00'}, + deploy_vm_standalones_java21_darwin_amd64: vm.vm_java_21_llvm + self.full_vm_build_darwin_amd64 + self.darwin_deploy + self.vm_base('darwin', 'amd64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", standalones=true) + {name: 'post-merge-deploy-vm-standalones-java21-darwin-amd64', capabilities+: ["!macmini_late_2014"], diskspace_required: "31GB", notify_groups:: ["deploy"], timelimit: '3:00:00'}, # Darwin/AARCH64 # - JDK-Latest deploy_vm_base_javaLatest_darwin_aarch64: vm.vm_java_Latest + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_base('latest') + {name: 'post-merge-deploy-vm-base-java-latest-darwin-aarch64', notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '1:45:00'}, - deploy_vm_standalones_javaLatest_darwin_aarch64: vm.vm_java_Latest + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components('latest', installables=false, standalones=true) + {name: 'post-merge-deploy-vm-standalones-java-latest-darwin-aarch64', diskspace_required: "31GB", notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '3:00:00'}, + deploy_vm_standalones_javaLatest_darwin_aarch64: vm.vm_java_Latest + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components('latest', standalones=true) + {name: 'post-merge-deploy-vm-standalones-java-latest-darwin-aarch64', diskspace_required: "31GB", notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '3:00:00'}, # - JDK21 deploy_vm_base_java21_darwin_aarch64: vm.vm_java_21 + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_base("java21") + {name: 'post-merge-deploy-vm-base-java21-darwin-aarch64', notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '1:45:00'}, - deploy_vm_installables_java21_darwin_aarch64: vm.vm_java_21 + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", installables=true, standalones=false) + {name: 'post-merge-deploy-vm-installables-java21-darwin-aarch64', diskspace_required: "31GB", notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '3:00:00'}, - deploy_vm_standalones_java21_darwin_aarch64: vm.vm_java_21 + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", installables=false, standalones=true) + {name: 'post-merge-deploy-vm-standalones-java21-darwin-aarch64', diskspace_required: "31GB", notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '3:00:00'}, + deploy_vm_standalones_java21_darwin_aarch64: vm.vm_java_21 + self.full_vm_build_darwin_aarch64 + self.darwin_deploy + self.vm_base('darwin', 'aarch64', 'post-merge', deploy=true) + self.deploy_graalvm_components("java21", standalones=true) + {name: 'post-merge-deploy-vm-standalones-java21-darwin-aarch64', diskspace_required: "31GB", notify_groups:: ["deploy"], notify_emails+: ["bernhard.urban-forster@oracle.com"], timelimit: '3:00:00'}, # Windows/AMD64 # - JDK-Latest deploy_vm_base_javaLatest_windows_amd64: vm.vm_java_Latest + self.svm_common_windows_amd64('Latest') + self.js_windows_common + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='Latest') + self.deploy_graalvm_base('latest') + self.deploy_build + {name: 'post-merge-deploy-vm-base-java-latest-windows-amd64', notify_groups:: ["deploy"], timelimit: '1:30:00'}, - deploy_vm_standalones_javaLatest_windows_amd64: vm.vm_java_Latest + self.svm_common_windows_amd64('Latest') + self.js_windows_common + self.sulong_windows + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='Latest') + self.deploy_graalvm_components('latest', installables=false, standalones=true) + self.deploy_build + {name: 'post-merge-deploy-vm-standalones-java-latest-windows-amd64', diskspace_required: "31GB", timelimit: '2:30:00', notify_groups:: ["deploy"]}, + deploy_vm_standalones_javaLatest_windows_amd64: vm.vm_java_Latest + self.svm_common_windows_amd64('Latest') + self.js_windows_common + self.sulong_windows + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='Latest') + self.deploy_graalvm_components('latest', standalones=true) + self.deploy_build + {name: 'post-merge-deploy-vm-standalones-java-latest-windows-amd64', diskspace_required: "31GB", timelimit: '2:30:00', notify_groups:: ["deploy"]}, # - JDK21 deploy_vm_base_java21_windows_amd64: vm.vm_java_21 + self.svm_common_windows_amd64("21") + self.js_windows_common + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='21') + self.deploy_graalvm_base("java21") + self.deploy_build + {name: 'post-merge-deploy-vm-base-java21-windows-amd64', notify_groups:: ["deploy"], timelimit: '1:30:00'}, - deploy_vm_installables_java21_windows_amd64: vm.vm_java_21 + self.svm_common_windows_amd64("21") + self.js_windows_common + self.sulong_windows + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='21') + self.deploy_graalvm_components("java21", installables=true, standalones=false) + self.deploy_build + {name: 'post-merge-deploy-vm-installables-java21-windows-amd64', diskspace_required: "31GB", timelimit: '2:30:00', notify_groups:: ["deploy"]}, - deploy_vm_standalones_java21_windows_amd64: vm.vm_java_21 + self.svm_common_windows_amd64("21") + self.js_windows_common + self.sulong_windows + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='21') + self.deploy_graalvm_components("java21", installables=false, standalones=true) + self.deploy_build + {name: 'post-merge-deploy-vm-standalones-java21-windows-amd64', diskspace_required: "31GB", timelimit: '2:30:00', notify_groups:: ["deploy"]}, + deploy_vm_standalones_java21_windows_amd64: vm.vm_java_21 + self.svm_common_windows_amd64("21") + self.js_windows_common + self.sulong_windows + self.vm_base('windows', 'amd64', 'post-merge', deploy=true, jdk_hint='21') + self.deploy_graalvm_components("java21", standalones=true) + self.deploy_build + {name: 'post-merge-deploy-vm-standalones-java21-windows-amd64', diskspace_required: "31GB", timelimit: '2:30:00', notify_groups:: ["deploy"]}, # # Deploy the GraalVM Espresso artifact (GraalVM Base + espresso - native image) diff --git a/vm/ci/ci_includes/vm.jsonnet b/vm/ci/ci_includes/vm.jsonnet index a5af5bc3d96f..efa4b1671f89 100644 --- a/vm/ci/ci_includes/vm.jsonnet +++ b/vm/ci/ci_includes/vm.jsonnet @@ -37,9 +37,6 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; short_name:: $.edition, setup+: [ ['set-export', 'VM_ENV', self.short_name], - ['set-export', 'RELEASE_CATALOG', 'https://www.graalvm.org/component-catalog/v2/graal-updater-component-catalog-java${BASE_JDK_SHORT_VERSION}.properties|{ee=GraalVM Enterprise Edition}rest://gds.oracle.com/api/20220101/'], - ['set-export', 'RELEASE_PRODUCT_ID', 'D53FAE8052773FFAE0530F15000AA6C6'], - ['set-export', 'SNAPSHOT_CATALOG', ['mx', 'urlrewrite', 'http://www.graalvm.org/catalog/ce/java${BASE_JDK_SHORT_VERSION}']], ['cd', $.vm_dir], ], }, @@ -55,9 +52,9 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; ], runAfter: [ 'post-merge-deploy-vm-base-java-latest-linux-amd64', - 'post-merge-deploy-vm-installables-standalones-java-latest-linux-amd64', + 'post-merge-deploy-vm-standalones-java-latest-linux-amd64', 'post-merge-deploy-vm-base-java-latest-linux-aarch64', - 'post-merge-deploy-vm-installables-standalones-java-latest-linux-aarch64', + 'post-merge-deploy-vm-standalones-java-latest-linux-aarch64', 'post-merge-deploy-vm-base-java-latest-darwin-amd64', 'post-merge-deploy-vm-standalones-java-latest-darwin-amd64', 'post-merge-deploy-vm-base-java-latest-darwin-aarch64', @@ -189,25 +186,25 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; # - # Deploy GraalVM Base and Installables + # Deploy GraalVM Base and Standalones # NOTE: After adding or removing deploy jobs, please make sure you modify ce-release-artifacts.json accordingly. # # Linux/AMD64 # - JDK-Latest vm_common.deploy_vm_base_javaLatest_linux_amd64, - vm_common.deploy_vm_installables_standalones_javaLatest_linux_amd64, + vm_common.deploy_vm_standalones_javaLatest_linux_amd64, # - JDK21 vm_common.deploy_vm_base_java21_linux_amd64, - vm_common.deploy_vm_installables_standalones_java21_linux_amd64, + vm_common.deploy_vm_standalones_java21_linux_amd64, # Linux/AARCH64 # - JDK-Latest vm_common.deploy_vm_base_javaLatest_linux_aarch64, - vm_common.deploy_vm_installables_standalones_javaLatest_linux_aarch64, + vm_common.deploy_vm_standalones_javaLatest_linux_aarch64, # - JDK21 vm_common.deploy_vm_base_java21_linux_aarch64, - vm_common.deploy_vm_installables_standalones_java21_linux_aarch64, + vm_common.deploy_vm_standalones_java21_linux_aarch64, # Darwin/AMD64 # - JDK-Latest @@ -215,8 +212,7 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; vm_common.deploy_vm_standalones_javaLatest_darwin_amd64, # - JDK21 vm_common.deploy_vm_base_java21_darwin_amd64, - vm_common.deploy_vm_installables_java21_darwin_amd64, - vm_common.deploy_vm_standalones_java21_darwin_amd64, + vm_common.deploy_vm_standalones_java21_darwin_amd64, # Darwin/AARCH64 # - JDK-Latest @@ -224,7 +220,6 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; vm_common.deploy_vm_standalones_javaLatest_darwin_aarch64, # - JDK21 vm_common.deploy_vm_base_java21_darwin_aarch64, - vm_common.deploy_vm_installables_java21_darwin_aarch64, vm_common.deploy_vm_standalones_java21_darwin_aarch64, # Windows/AMD64 @@ -233,7 +228,6 @@ local graal_common = import '../../../ci/ci_common/common.jsonnet'; vm_common.deploy_vm_standalones_javaLatest_windows_amd64, # - JDK21 vm_common.deploy_vm_base_java21_windows_amd64, - vm_common.deploy_vm_installables_java21_windows_amd64, vm_common.deploy_vm_standalones_java21_windows_amd64, # diff --git a/vm/mx.vm/gu-deprecated b/vm/mx.vm/gu-deprecated deleted file mode 100755 index ccf0e9476886..000000000000 --- a/vm/mx.vm/gu-deprecated +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash -# -# ---------------------------------------------------------------------------------------------------- -# -# Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -# ---------------------------------------------------------------------------------------------------- - -cat <nul -) -if exist %gu_post_copy_contents% ( - del /f /q %gu_post_copy_contents% >nul -) - -if "%VERBOSE_GRAALVM_LAUNCHERS%"=="true" echo on - -"%root_dir%\bin\java" %GU_OPTS% -cp "%realcp%" org.graalvm.component.installer.ComponentInstaller %* - -if errorlevel 11 ( - echo Retrying operations on locked files... - for /f "delims=|" %%f in (%gu_post_delete_list%) do ( - del /f /s /q "%%f" >nul - if exist "%%f\" ( - rd /s /q "%%f" >nul - ) - ) - - for /f "delims=| tokens=1,2" %%f in (%gu_post_copy_contents%) do ( - copy /y /b "%%g\*.*" "%%f" >nul - del /f /s /q "%%g" >nul - rd /s /q "%%g" >nul - ) -) -:end diff --git a/vm/mx.vm/mx_vm.py b/vm/mx.vm/mx_vm.py index bf6e08e2cc66..e568ce908102 100644 --- a/vm/mx.vm/mx_vm.py +++ b/vm/mx.vm/mx_vm.py @@ -43,9 +43,6 @@ """:type: mx.SourceSuite | mx.Suite""" -gu_build_args = [] # externalized to simplify extensions - - @mx.command(_suite.name, "local-path-to-url") def local_path_to_url(args): """Print the url representation of a canonicalized path""" @@ -56,54 +53,6 @@ def local_path_to_url(args): print(pathlib.Path(os.path.realpath(args.path)).as_uri()) -if mx_sdk_vm_impl.USE_LEGACY_GU: - gu_component = mx_sdk_vm.GraalVmJdkComponent( - suite=_suite, - name='Component installer', - short_name='gu', - dir_name='installer', - license_files=[], - third_party_license_files=[], - dependencies=['sdk'], - jar_distributions=[ - 'vm:INSTALLER', - 'truffle:TRUFFLE_JSON' - ], - support_distributions=['vm:INSTALLER_GRAALVM_SUPPORT'], - launcher_configs=[ - mx_sdk_vm.LauncherConfig( - destination="bin/", - jar_distributions=[ - 'vm:INSTALLER', - 'truffle:TRUFFLE_JSON' - ], - dir_jars=True, - main_class="org.graalvm.component.installer.ComponentInstaller", - link_at_build_time=False, - build_args=gu_build_args, - # Please see META-INF/native-image in the project for custom build options for native-image - is_sdk_launcher=True, - custom_launcher_script="mx.vm/gu.cmd" if mx.is_windows() else None, - ), - ], - stability="supported", - ) -else: - gu_component = mx_sdk_vm.GraalVmJdkComponent( - suite=_suite, - name='Deprecated GraalVM Updater launchers', - short_name='gu', - dir_name='installer', - provided_executables=['bin/gu.cmd' if mx.is_windows() else 'bin/gu'], - license_files=[], - third_party_license_files=[], - dependencies=[], - support_distributions=['vm:INSTALLER_DEPRECATED_GRAALVM_SUPPORT'], - stability="supported", - ) -mx_sdk_vm.register_graalvm_component(gu_component) - - mx_sdk_vm.register_graalvm_component(mx_sdk_vm.GraalVmComponent( suite=_suite, name='GraalVM license files', @@ -190,12 +139,12 @@ def local_path_to_url(args): # pylint: disable=line-too-long ce_unchained_components = ['bnative-image-configure', 'cmp', 'lg', 'ni', 'nic', 'nil', 'nr_lib_jvmcicompiler', 'sdkc', 'sdkni', 'svm', 'svmsl', 'svmt', 'tflc', 'tflsm'] -ce_components_minimal = ['bpolyglot', 'cmp', 'cov', 'dap', 'gu', 'gvm', 'ins', 'insight', 'insightheap', 'lg', 'libpoly', 'lsp', 'nfi-libffi', 'nfi', 'poly', 'polynative', 'pro', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'spolyglot', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json'] +ce_components_minimal = ['bpolyglot', 'cmp', 'cov', 'dap', 'gvm', 'ins', 'insight', 'insightheap', 'lg', 'libpoly', 'lsp', 'nfi-libffi', 'nfi', 'poly', 'polynative', 'pro', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'spolyglot', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json'] ce_components = ce_components_minimal + ['nr_lib_jvmcicompiler', 'bnative-image-configure', 'ni', 'nic', 'nil', 'svm', 'svmt', 'svmnfi', 'svmsl'] ce_ruby_components = ['antlr4', 'cmp', 'cov', 'dap', 'gvm', 'icu4j', 'ins', 'insight', 'insightheap', 'lg', 'llp', 'llrc', 'llrlf', 'llrn', 'lsp', 'nfi-libffi', 'nfi', 'pro', 'rby', 'rbyl', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json'] -ce_python_components = ['antlr4', 'sllvmvm', 'bpolybench', 'bpolyglot', 'cmp', 'cov', 'dap', 'dis', 'gu', 'gvm', 'icu4j', 'xz', 'ins', 'insight', 'insightheap', 'lg', 'libpoly', 'llp', 'llrc', 'llrl', 'llrlf', 'llrn', 'lsp', 'nfi-libffi', 'nfi', 'pbm', 'pmh', 'poly', 'polynative', 'pro', 'pyn', 'pynl', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'spolyglot', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json'] +ce_python_components = ['antlr4', 'sllvmvm', 'bpolybench', 'bpolyglot', 'cmp', 'cov', 'dap', 'dis', 'gvm', 'icu4j', 'xz', 'ins', 'insight', 'insightheap', 'lg', 'libpoly', 'llp', 'llrc', 'llrl', 'llrlf', 'llrn', 'lsp', 'nfi-libffi', 'nfi', 'pbm', 'pmh', 'poly', 'polynative', 'pro', 'pyn', 'pynl', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'spolyglot', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json'] ce_fastr_components = ce_components + llvm_components + ['antlr4', 'xz', 'sllvmvm', 'llp', 'bnative-image', 'snative-image-agent', 'R', 'bRMain', 'bnative-image-configure', 'llrc', 'snative-image-diagnostics-agent', 'llrn', 'llrl', 'llrlf'] -ce_no_native_components = ['bpolyglot', 'cmp', 'cov', 'dap', 'gu', 'gvm', 'ins', 'insight', 'insightheap', 'lsp', 'nfi-libffi', 'nfi', 'polynative', 'pro', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'spolyglot', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json', 'libpoly', 'poly'] +ce_no_native_components = ['bpolyglot', 'cmp', 'cov', 'dap', 'gvm', 'ins', 'insight', 'insightheap', 'lsp', 'nfi-libffi', 'nfi', 'polynative', 'pro', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'spolyglot', 'tfl', 'tfla', 'tflc', 'tflm', 'truffle-json', 'libpoly', 'poly'] # Main GraalVMs mx_sdk_vm.register_vm_config('community', ce_unchained_components, _suite, env_file='ce-win') @@ -215,8 +164,8 @@ def local_path_to_url(args): mx_sdk_vm.register_vm_config('ce-no_native', ce_no_native_components, _suite) mx_sdk_vm.register_vm_config('libgraal', ['cmp', 'lg', 'sdkc', 'tflc'], _suite) mx_sdk_vm.register_vm_config('toolchain-only', ['antlr4', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'tfl', 'tfla', 'tflc', 'tflm', 'nfi-libffi', 'nfi', 'cmp', 'llp', 'llrc', 'llrlf', 'llrn'], _suite) -mx_sdk_vm.register_vm_config('libgraal-bash', llvm_components + ['cmp', 'gu', 'gvm', 'lg', 'nfi-libffi', 'nfi', 'poly', 'polynative', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'tfl', 'tfla', 'tflc', 'tflm', 'bpolyglot'], _suite, env_file=False) -mx_sdk_vm.register_vm_config('toolchain-only-bash', llvm_components + ['antlr4', 'tfl', 'tfla', 'tflc', 'tflm', 'gu', 'gvm', 'polynative', 'llp', 'nfi-libffi', 'nfi', 'svml', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'llrc', 'llrlf', 'llrn', 'cmp'], _suite, env_file=False) +mx_sdk_vm.register_vm_config('libgraal-bash', llvm_components + ['cmp', 'gvm', 'lg', 'nfi-libffi', 'nfi', 'poly', 'polynative', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'tfl', 'tfla', 'tflc', 'tflm', 'bpolyglot'], _suite, env_file=False) +mx_sdk_vm.register_vm_config('toolchain-only-bash', llvm_components + ['antlr4', 'tfl', 'tfla', 'tflc', 'tflm', 'gvm', 'polynative', 'llp', 'nfi-libffi', 'nfi', 'svml', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'llrc', 'llrlf', 'llrn', 'cmp'], _suite, env_file=False) mx_sdk_vm.register_vm_config('ce', llvm_components + ['antlr4', 'java', 'libpoly', 'sjavavm', 'spolyglot', 'ejvm', 'sjsvm', 'sllvmvm', 'bnative-image', 'srubyvm', 'pynl', 'spythonvm', 'pyn', 'cmp', 'gwa', 'gwal', 'icu4j', 'xz', 'js', 'jsl', 'jss', 'lg', 'llp', 'nfi-libffi', 'nfi', 'ni', 'nil', 'pbm', 'pmh', 'pbi', 'rby', 'rbyl', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'llrc', 'llrn', 'llrl', 'llrlf', 'snative-image-agent', 'snative-image-diagnostics-agent', 'svm', 'svmt', 'svmnfi', 'svmsl', 'swasmvm', 'tfl', 'tfla', 'tflc', 'tflm'], _suite, env_file='polybench-ce') mx_sdk_vm.register_vm_config('ce', ['bnative-image', 'bpolybench', 'cmp', 'icu4j', 'xz', 'lg', 'nfi', 'ni', 'nil', 'pbi', 'pbm', 'pmh', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'snative-image-agent', 'snative-image-diagnostics-agent', 'svm', 'svmt', 'svmnfi', 'svmsl', 'tfl', 'tfla', 'tflc', 'tflm'], _suite, dist_name='ce', env_file='polybench-ctw-ce') mx_sdk_vm.register_vm_config('ce', ['pbm', 'pmh', 'pbi', 'ni', 'icu4j', 'xz', 'js', 'jsl', 'jss', 'lg', 'nfi-libffi', 'nfi', 'tfl', 'tfla', 'tflc', 'svm', 'svmt', 'nil', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'cmp', 'tflm', 'svmnfi', 'svmsl', 'bnative-image', 'sjsvm', 'snative-image-agent', 'snative-image-diagnostics-agent'], _suite, env_file='polybench-nfi-ce') @@ -225,7 +174,7 @@ def local_path_to_url(args): if mx.get_os() == 'windows': mx_sdk_vm.register_vm_config('svm', ['bnative-image', 'bnative-image-configure', 'bpolyglot', 'cmp', 'gvm', 'nfi-libffi', 'nfi', 'ni', 'nil', 'nju', 'njucp', 'nic', 'poly', 'polynative', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'snative-image-agent', 'snative-image-diagnostics-agent', 'svm', 'svmt', 'svmnfi', 'svmsl', 'tfl', 'tfla', 'tflc', 'tflm'], _suite, env_file=False) else: - mx_sdk_vm.register_vm_config('svm', ['bnative-image', 'bnative-image-configure', 'bpolyglot', 'cmp', 'gu', 'gvm', 'nfi-libffi', 'nfi', 'ni', 'nil', 'nju', 'njucp', 'nic', 'poly', 'polynative', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'snative-image-agent', 'snative-image-diagnostics-agent', 'svm', 'svmt', 'svmnfi', 'svmsl', 'svml', 'tfl', 'tfla', 'tflc', 'tflm'], _suite, env_file=False) + mx_sdk_vm.register_vm_config('svm', ['bnative-image', 'bnative-image-configure', 'bpolyglot', 'cmp', 'gvm', 'nfi-libffi', 'nfi', 'ni', 'nil', 'nju', 'njucp', 'nic', 'poly', 'polynative', 'rgx', 'sdk', 'sdkni', 'sdkc', 'sdkl', 'snative-image-agent', 'snative-image-diagnostics-agent', 'svm', 'svmt', 'svmnfi', 'svmsl', 'svml', 'tfl', 'tfla', 'tflc', 'tflm'], _suite, env_file=False) # pylint: enable=line-too-long diff --git a/vm/mx.vm/mx_vm_gate.py b/vm/mx.vm/mx_vm_gate.py index e6a8d0a1f2b0..fec2c4ceb8af 100644 --- a/vm/mx.vm/mx_vm_gate.py +++ b/vm/mx.vm/mx_vm_gate.py @@ -75,17 +75,6 @@ class VmGateTasks: truffle_unchained = 'truffle-unchained' maven_downloader = 'maven-downloader' -def _unittest_config_participant(config): - vmArgs, mainClass, mainClassArgs = config - # This is required by org.graalvm.component.installer.CatalogIterableTest - vmArgs += [ - '--add-exports=java.base/jdk.internal.loader=ALL-UNNAMED', - '--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED', - ] - return vmArgs, mainClass, mainClassArgs - -mx_unittest.add_config_participant(_unittest_config_participant) - def _get_CountUppercase_vmargs(): cp = mx.project("jdk.graal.compiler.test").classpath_repr() return ['-cp', cp, 'jdk.graal.compiler.test.CountUppercase'] diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 8df577803094..829b6bb1b5c1 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -83,30 +83,6 @@ }, "projects": { - "org.graalvm.component.installer" : { - "subDir" : "src", - "sourceDirs" : ["src"], - "javaCompliance" : "17+", - "license" : "GPLv2-CPE", - "checkstyle": "org.graalvm.polybench", - "dependencies": [ - "sdk:LAUNCHER_COMMON", - "truffle:TRUFFLE_JSON", - ], - "requires" : ["java.logging"], - }, - "org.graalvm.component.installer.test" : { - "subDir" : "src", - "sourceDirs" : ["src"], - "dependencies": [ - "mx:JUNIT", - "org.graalvm.component.installer" - ], - "javaCompliance" : "17+", - "checkstyle": "org.graalvm.polybench", - "license" : "GPLv2-CPE", - "requires" : ["java.logging"], - }, "org.graalvm.polybench" : { "subDir" : "src", "sourceDirs" : ["src"], @@ -180,73 +156,9 @@ "urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/visualvm/visualvm-944-linux-amd64.tar.gz"], "digest" : "sha512:72982ca01cce9dfa876687ec7b9627b81e241e6cddc8dedb976a5d06d058a067f83f5c063dc07d7ed19730ffb54af8343eae8ca0cc156353f7b18530eef73c50" }, - "ORG_NETBEANS_API_ANNOTATIONS_COMMON" : { - "digest" : "sha512:37e9cee0756a3f84e3e6352ed3d358169855d16cdda2300eb5041219c867abf886db2de41fe79c37f39123eaac310041f9a2e65aa1b9a7e8384528cfbd40de5b", - "maven" : { - "groupId" : "org.netbeans.api", - "artifactId" : "org-netbeans-api-annotations-common", - "version" : "RELEASE123", - }, - }, }, "distributions": { - "INSTALLER": { - "subDir": "src", - "mainClass": "org.graalvm.component.installer.ComponentInstaller", - "dependencies": [ - "org.graalvm.component.installer", - ], - "distDependencies": [ - "sdk:LAUNCHER_COMMON", - "truffle:TRUFFLE_JSON", - ], - "maven" : False, - }, - "INSTALLER_TESTS": { - "subDir": "src", - "dependencies": ["org.graalvm.component.installer.test"], - "exclude": [ - "mx:HAMCREST", - "mx:JUNIT", - ], - "distDependencies": [ - "INSTALLER", - ], - "maven": False, - }, - "INSTALLER_GRAALVM_SUPPORT": { - "native": True, - "platformDependent": True, - "description": "GraalVM Installer support distribution for the GraalVM", - "layout": { - "components/polyglot/.registry" : "string:", - }, - "maven": False, - }, - "INSTALLER_DEPRECATED_GRAALVM_SUPPORT": { - "native": True, - "description": "Deprecated GraalVM Updater launchers support for the GraalVM", - "platformDependent": True, - "os": { - "linux": { - "layout": { - "bin/gu": "file:mx.vm/gu-deprecated", - }, - }, - "darwin": { - "layout": { - "bin/gu": "file:mx.vm/gu-deprecated", - }, - }, - "windows": { - "layout": { - "bin/gu.cmd": "file:mx.vm/gu-deprecated.cmd", - }, - }, - }, - "maven": False, - }, "VM_GRAALVM_SUPPORT": { "native": True, "description": "VM support distribution for the GraalVM", diff --git a/vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader b/vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader deleted file mode 100644 index 9d8610214f8d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader +++ /dev/null @@ -1 +0,0 @@ -org.graalvm.component.installer.DirectoryArchiveReader \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory b/vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory deleted file mode 100644 index def672b60bcd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory +++ /dev/null @@ -1 +0,0 @@ -org.graalvm.component.installer.persist.test.TestCatalog diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CatalogIterableTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CatalogIterableTest.java deleted file mode 100644 index ca3ff9e2b7f6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CatalogIterableTest.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import org.graalvm.component.installer.remote.CatalogIterable; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.graalvm.component.installer.DownloadURLIterable.DownloadURLParam; -import org.graalvm.component.installer.jar.JarArchive; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -public class CatalogIterableTest extends CommandTestBase { - @Rule public final ProxyResource proxyResource = new ProxyResource(); - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - } - - @After - public void tearDown() throws Exception { - if (param != null) { - param.close(); - } - } - - @Test - public void testRemoteNames() throws Exception { - initRemoteComponent("persist/data/truffleruby2.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test"); - - assertEquals("test", param.getSpecification()); - assertEquals("testComponent", param.getDisplayName()); - assertFalse(param.isComplete()); - assertFalse(Handler.isVisited(url)); - } - - @Test - public void testCreateMetaLoader() throws Exception { - initRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test"); - - MetadataLoader ldr = param.createMetaLoader(); - ldr.setNoVerifySymlinks(false); - ldr.loadPaths(); - ldr.loadPermissions(); - ldr.loadSymlinks(); - ComponentInfo meta = ldr.getComponentInfo(); - - assertEquals("ruby", meta.getId()); - assertNull(meta.getInfoPath()); - assertNull(meta.getLicensePath()); - assertTrue(meta.getPaths().isEmpty()); - assertEquals("TruffleRuby 0.33-dev", meta.getName()); - assertEquals("0.33-dev", meta.getVersionString()); - - assertFalse(Handler.isVisited(url)); - } - - @Test - public void testCreateFileLoader() throws Exception { - initRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test"); - - MetadataLoader ldr = param.createFileLoader(); - ldr.setNoVerifySymlinks(false); - ldr.loadPaths(); - ldr.loadPermissions(); - ldr.loadSymlinks(); - ComponentInfo meta = ldr.getComponentInfo(); - - assertEquals("ruby", meta.getId()); - assertNull(meta.getInfoPath()); - assertFalse(meta.getPaths().isEmpty()); - assertEquals("TruffleRuby 0.33-dev", meta.getName()); - assertEquals("0.33-dev", meta.getVersionString()); - - assertTrue(Handler.isVisited(url)); - } - - @Test - public void testVerifyRemoteJars() throws Exception { - initRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", "testComponent", "test"); - info.setShaDigest(SystemUtils.toHashBytes("d3a45ea326b379cc3d543cc56130ee9bd395fd1c1d51a470e8c2c8af1129829c")); - - try { - exception.expect(IOException.class); - exception.expectMessage("ERR_FileDigestError"); - param.createFileLoader(); - } finally { - assertTrue(Handler.isVisited(url)); - } - } - - void addRemoteComponent(String relative, String u, boolean addParam) throws IOException { - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev"); - initRemoteComponent(relative, u, null, null); - catalogStorage.installed.add(info); - if (addParam) { - components.add(param); - } - } - - @Test - public void testReadComponentMetadataNoNetwork() throws Exception { - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - textParams.add("ruby"); - CatalogIterable cit = new CatalogIterable(this, this); - assertTrue(cit.iterator().hasNext()); - for (ComponentParam p : cit) { - URL remoteU = p.createMetaLoader().getComponentInfo().getRemoteURL(); - assertEquals(url, remoteU); - } - assertFalse(Handler.isVisited(url)); - } - - @Test - public void testUnknownComponentSpecified() throws Exception { - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_UnknownComponentId"); - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - textParams.add("r"); - CatalogIterable cit = new CatalogIterable(this, this); - assertTrue(cit.iterator().hasNext()); - cit.iterator().next(); - } - - /** - * Checks that if user mistypes a filename instead of component ID, an informative note is - * printed. - */ - @Test - public void testUnknownComponentButExistingFile() throws Exception { - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_UnknownComponentMaybeFile"); - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - File mistyped = folder.newFile("mistyped-component.jar"); - textParams.add(mistyped.getPath()); - CatalogIterable cit = new CatalogIterable(this, this); - assertTrue(cit.iterator().hasNext()); - cit.iterator().next(); - } - - @Test - public void testMetaAccessesDirectURL() throws Exception { - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false); - components.add(param); - - URL remoteU = rparam.createMetaLoader().getComponentInfo().getRemoteURL(); - assertEquals(url, remoteU); - assertTrue(Handler.isVisited(url)); - assertTrue(rparam.isComplete()); - } - - @Test - public void testDirectURLAccessedJustOnce() throws Exception { - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false); - components.add(param); - - URL remoteU = rparam.createMetaLoader().getComponentInfo().getRemoteURL(); - assertEquals(url, remoteU); - assertTrue(Handler.isVisited(url)); - assertTrue(rparam.isComplete()); - - Handler.clearVisited(); - - Archive jf = rparam.getArchive(); - assertNotNull(jf); - assertFalse(Handler.isVisited(url)); - } - - @Test - public void testDirectURLJarClosedAfterMeta() throws Exception { - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false); - components.add(param); - - URL remoteU = rparam.createMetaLoader().getComponentInfo().getRemoteURL(); - assertEquals(url, remoteU); - JarArchive jf = (JarArchive) rparam.getArchive(); - assertNotNull(jf.getEntry("META-INF")); - - rparam.close(); - - exception.expect(IllegalStateException.class); - jf.getEntry("META-INF"); - } - - @Test - public void testDirectURLJarClosedAfterJar() throws Exception { - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - rparam = new DownloadURLParam(url, rparam.getDisplayName(), rparam.getSpecification(), this, false); - components.add(param); - JarArchive jf = (JarArchive) rparam.getArchive(); - assertNotNull(jf.getEntry("META-INF")); - rparam.close(); - exception.expect(IllegalStateException.class); - jf.getEntry("META-INF"); - } - - @Test - public void testURLDoesNotExist() throws Exception { - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev"); - addRemoteComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip", false); - textParams.add("ruby"); - Handler.bind(url.toString(), new URLConnection(url) { - @Override - public InputStream getInputStream() throws IOException { - connect(); - return clu.openStream(); - } - - @Override - public String getHeaderField(int n) { - try { - connect(); - } catch (IOException ex) { - Logger.getLogger(CatalogIterableTest.class.getName()).log(Level.SEVERE, null, ex); - } - return super.getHeaderField(n); - } - - @Override - public Map> getHeaderFields() { - try { - connect(); - } catch (IOException ex) { - Logger.getLogger(CatalogIterableTest.class.getName()).log(Level.SEVERE, null, ex); - } - return super.getHeaderFields(); - } - - @Override - public void connect() throws IOException { - throw new FileNotFoundException(); - } - }); - - CatalogIterable cit = new CatalogIterable(this, this); - ComponentParam rubyComp = cit.iterator().next(); - - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_ErrorDownloadingNotExist"); - - rubyComp.createFileLoader().getComponentInfo(); - } - - private static final String TEST_CATALOG_URL = "test://release/catalog.properties"; - private RemoteCatalogDownloader downloader; - - private void setupCatalog() throws Exception { - this.storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "19.3-dev"); - String relSpec = "commands/cataloginstallDeps.properties"; - URL u = getClass().getResource(relSpec); - Handler.bind(TEST_CATALOG_URL, u); - - downloader = new RemoteCatalogDownloader(this, this, SystemUtils.toURL(TEST_CATALOG_URL)); - this.registry = new CatalogContents(this, downloader.getStorage(), getLocalRegistry()); - } - - /** - * Checks that a parameter without wildcards will act as a literal. - */ - @Test - public void testNoWildcards() throws Exception { - setupCatalog(); - textParams.add("ruby"); - CatalogIterable cit = new CatalogIterable(this, this); - Iterator comps = cit.iterator(); - ComponentParam c; - - c = comps.next(); - assertFalse(comps.hasNext()); - assertEquals("org.graalvm.ruby", c.createMetaLoader().getComponentInfo().getId()); - } - - @Test - public void testAllComponents() throws Exception { - setupCatalog(); - textParams.add("*"); - CatalogIterable cit = new CatalogIterable(this, this); - Iterator comps = cit.iterator(); - - List fullIds = new ArrayList<>(); - for (; comps.hasNext();) { - ComponentParam cp = comps.next(); - fullIds.add(cp.createMetaLoader().getComponentInfo().getId()); - } - assertEquals(5, fullIds.size()); - } - - @Test - public void testSelectSomeComponents() throws Exception { - setupCatalog(); - textParams.add("*mage"); - textParams.add("llvm*"); - CatalogIterable cit = new CatalogIterable(this, this); - Iterator comps = cit.iterator(); - - List fullIds = new ArrayList<>(); - for (; comps.hasNext();) { - ComponentParam cp = comps.next(); - fullIds.add(cp.createMetaLoader().getComponentInfo().getId()); - } - assertEquals(2, fullIds.size()); - } - - @Test - public void testWildardSorted() throws Exception { - setupCatalog(); - textParams.add("r*"); - CatalogIterable cit = new CatalogIterable(this, this); - Iterator comps = cit.iterator(); - - List fullIds = new ArrayList<>(); - for (; comps.hasNext();) { - ComponentParam cp = comps.next(); - fullIds.add(cp.createMetaLoader().getComponentInfo().getId()); - } - assertEquals(2, fullIds.size()); - assertEquals("org.graalvm.r", fullIds.get(0)); - assertEquals("org.graalvm.ruby", fullIds.get(1)); - } - - @Test - public void testMixWildcardsAndLiterals() throws Exception { - setupCatalog(); - textParams.add("r*"); - textParams.add("ruby"); - CatalogIterable cit = new CatalogIterable(this, this); - Iterator comps = cit.iterator(); - - List fullIds = new ArrayList<>(); - for (; comps.hasNext();) { - ComponentParam cp = comps.next(); - fullIds.add(cp.createMetaLoader().getComponentInfo().getId()); - } - assertEquals(3, fullIds.size()); - assertEquals("org.graalvm.ruby", fullIds.get(1)); - assertEquals("org.graalvm.ruby", fullIds.get(2)); - } - - @Override - public FileDownloader configureDownloader(ComponentInfo ci, FileDownloader dn) { - return dn; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ChunkedConnection.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ChunkedConnection.java deleted file mode 100644 index 4ea9081c6e1d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ChunkedConnection.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.concurrent.Semaphore; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.graalvm.component.installer.remote.FileDownloaderTest; - -public class ChunkedConnection extends HttpURLConnection { - public InputStream delegate; - public volatile long nextChunk = Long.MAX_VALUE; - public Semaphore nextSem = new Semaphore(0); - public Semaphore reachedSem = new Semaphore(0); - public URLConnection original; - public volatile IOException readException; - - public ChunkedConnection(URL url, URLConnection original) { - super(url); - this.original = original; - } - - @Override - public void connect() throws IOException { - original.connect(); - } - - @Override - public String getHeaderField(String name) { - return original.getHeaderField(name); - } - - @Override - public InputStream getInputStream() throws IOException { - connect(); - delegate = original.getInputStream(); - return new InputStream() { - @Override - public int read() throws IOException { - synchronized (ChunkedConnection.this) { - if (nextChunk == 0) { - reachedSem.release(); - try { - nextSem.acquire(); - } catch (InterruptedException ex) { - Logger.getLogger(FileDownloaderTest.class.getName()).log(Level.SEVERE, null, ex); - } - } - if (readException != null) { - throw readException; - } - nextChunk--; - return delegate.read(); - } - } - }; - } - - @Override - public long getContentLengthLong() { - return original.getContentLengthLong(); - } - - @Override - public int getContentLength() { - return original.getContentLength(); - } - - @Override - public void disconnect() { - } - - @Override - public boolean usingProxy() { - return false; - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CommandTestBase.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CommandTestBase.java deleted file mode 100644 index 88248b18e5f5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/CommandTestBase.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.jar.JarFile; -import org.graalvm.component.installer.DownloadURLIterable.DownloadURLParam; -import org.graalvm.component.installer.commands.MockStorage; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.model.GraalEdition; -import org.graalvm.component.installer.os.DefaultFileOperations; -import org.graalvm.component.installer.os.WindowsFileOperations; -import org.graalvm.component.installer.persist.ComponentPackageLoader; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.persist.test.Handler; -import org.graalvm.component.installer.remote.RemoteComponentParam; -import org.graalvm.component.installer.remote.CatalogIterable.CatalogItemParam; -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; - -public class CommandTestBase extends TestBase implements CommandInput, SoftwareChannel, ComponentCatalog.DownloadInterceptor { - @Rule public ExpectedException exception = ExpectedException.none(); - protected JarFile componentJarFile; - @Rule public TemporaryFolder folder = new TemporaryFolder(); - - protected Path targetPath; - - protected FileOperations fileOps; - protected MockStorage storage; - protected MockStorage catalogStorage; - protected ComponentCatalog registry; - protected ComponentRegistry localRegistry; - - protected List files = new ArrayList<>(); - protected List components = new ArrayList<>(); - protected List textParams = new ArrayList<>(); - protected Map options = new HashMap<>(); - - protected Map propParameters = new HashMap<>(); - protected Map envParameters = new HashMap<>(); - - ComponentParam param; - RemoteComponentParam rparam; - URL url; - URL clu; - ComponentInfo info; - - @SuppressWarnings("this-escape") - public CommandTestBase() { - fileOps = SystemUtils.isWindows() ? new WindowsFileOperations() : new DefaultFileOperations(); - fileOps.init(this); - } - - protected void initRemoteComponent(String relativeJar, String u, String disp, String spec) throws IOException { - clu = getClass().getResource(relativeJar); - url = SystemUtils.toURL(u); - Handler.bind(url.toString(), clu); - - File f = dataFile(relativeJar).toFile(); - JarFile jf = new JarFile(f, false); - ComponentPackageLoader cpl = new JarMetaLoader(jf, this); - info = cpl.getComponentInfo(); - // unknown in catalog metadata - info.setLicensePath(null); - info.setRemoteURL(url); - param = rparam = new CatalogItemParam(this, info, disp, spec, this, false); - } - - protected void initURLComponent(String relativeJar, String spec) throws IOException { - clu = getClass().getResource(relativeJar); - url = SystemUtils.toURL(spec); - Handler.bind(url.toString(), clu); - - File f = dataFile(relativeJar).toFile(); - JarFile jf = new JarFile(f, false); - ComponentPackageLoader cpl = new JarMetaLoader(jf, this); - info = cpl.getComponentInfo(); - // unknown in catalog metadata - info.setLicensePath(null); - info.setRemoteURL(url); - param = rparam = new DownloadURLParam(url, spec, spec, this, false); - } - - protected ComponentIterable paramIterable; - - boolean verifyJars; - - @Override - public FileOperations getFileOperations() { - return fileOps; - } - - protected class CompIterableImpl implements ComponentIterable { - @Override - public void setVerifyJars(boolean verify) { - verifyJars = verify; - } - - @Override - public ComponentParam createParam(String cmdString, ComponentInfo nfo) { - return null; - } - - @Override - public Iterator iterator() { - return new Iterator<>() { - private Iterator pit = components.iterator(); - private Iterator fit; - { - FileIterable ff = new FileIterable(CommandTestBase.this, CommandTestBase.this); - ff.setVerifyJars(verifyJars); - fit = ff.iterator(); - } - - @Override - public boolean hasNext() { - return fit.hasNext() || pit.hasNext(); - } - - @Override - public ComponentParam next() { - ComponentParam p = null; - - if (pit.hasNext()) { - p = pit.next(); - // discard one parameter from files: - files.remove(0); - if (p != null) { - return p; - } - } - return fit.next(); - } - - }; - } - - @Override - public ComponentIterable matchVersion(Version.Match m) { - return this; - } - - @Override - public ComponentIterable allowIncompatible() { - return this; - } - } - - protected ComponentIterable iterableInstance; - - protected ComponentIterable createComponentIterable() { - if (iterableInstance != null) { - return iterableInstance; - } - return new CompIterableImpl(); - } - - @Override - public ComponentIterable existingFiles() throws FailedOperationException { - if (paramIterable != null) { - return paramIterable; - } - return createComponentIterable(); - } - - @Override - public String requiredParameter() throws FailedOperationException { - if (!textParams.isEmpty()) { - return textParams.remove(0); - } - return files.remove(0).toString(); - } - - @Override - public String nextParameter() { - if (hasParameter()) { - return requiredParameter(); - } - return null; - } - - @Override - public String peekParameter() { - if (!textParams.isEmpty()) { - return textParams.get(0); - } - return files.isEmpty() ? null : files.get(0).toString(); - } - - @Override - public boolean hasParameter() { - return (!textParams.isEmpty() || !files.isEmpty()); - } - - @Override - public Path getGraalHomePath() { - return targetPath; - } - - @Override - public ComponentCatalog getRegistry() { - if (registry == null) { - registry = getCatalogFactory().createComponentCatalog(this); - } - return registry; - } - - @Override - public ComponentRegistry getLocalRegistry() { - if (localRegistry == null) { - localRegistry = new ComponentRegistry(this, storage); - } - return localRegistry; - } - - @Override - public String optValue(String option) { - return options.get(option); - } - - @Before - public void setUp() throws Exception { - targetPath = folder.newFolder("inst").toPath(); - storage = new MockStorage(); - catalogStorage = new MockStorage(); - fileOps.setRootPath(targetPath); - } - - @Override - public FileDownloader processDownloader(ComponentInfo ci, FileDownloader dn) { - return dn; - } - - @Override - public FileDownloader configureDownloader(ComponentInfo ci, FileDownloader dn) { - return dn; - } - - @Override - public ComponentStorage getStorage() { - return catalogStorage; - } - - @Override - public CatalogFactory getCatalogFactory() { - return new CatalogFactory() { - @Override - public ComponentCatalog createComponentCatalog(CommandInput input) { - if (registry != null) { - return registry; - } else { - return new CatalogContents(CommandTestBase.this, catalogStorage, getLocalRegistry()); - } - } - - @Override - public List listEditions(ComponentRegistry targetGraalVM) { - return Collections.emptyList(); - } - }; - } - - @Override - public String getParameter(String key, boolean cmdLine) { - return (cmdLine ? propParameters : envParameters).get(key); - } - - @Override - public Map parameters(boolean cmdLine) { - return (cmdLine ? propParameters : envParameters); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ComponentInstallerTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ComponentInstallerTest.java deleted file mode 100644 index a404da75fa2d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/ComponentInstallerTest.java +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.CodeSource; -import java.security.ProtectionDomain; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.stream.Collectors; -import org.junit.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Assume; -import org.junit.Test; -import java.net.MalformedURLException; -import java.util.stream.Stream; - -/** - * - * @author sdedic - */ -public class ComponentInstallerTest extends CommandTestBase { - StringBuilder message = new StringBuilder(); - boolean cmdReported; - String currentCmd; - - void startCommand(String cmd) { - cmdReported = false; - currentCmd = cmd; - } - - void reportOption(String k) { - if (k.length() == 1 && !Character.isLetterOrDigit(k.charAt(0))) { - return; - } - if (message.length() > 0) { - message.append(", "); - } - if (!cmdReported) { - cmdReported = true; - message.append("Command ").append(currentCmd).append(": "); - } - message.append(k); - } - - /** - * Checks that no command defines an option that clash with the global one. - */ - @Test - public void testOptionClashBetweenCommandAndGlobal() throws Exception { - ComponentInstaller.initCommands(); - for (String cmd : ComponentInstaller.commands.keySet()) { - startCommand(cmd); - InstallerCommand c = ComponentInstaller.commands.get(cmd); - Map opts = c.supportedOptions(); - for (String k : opts.keySet()) { - String v = opts.get(k); - if ("X".equals(v)) { - continue; - } - if (ComponentInstaller.globalOptions.containsKey(k) && - !ComponentInstaller.componentOptions.containsKey(k)) { - reportOption(k); - } - } - } - if (message.length() > 0) { - Assert.fail("Command options clashes with the global: " + message.toString()); - } - } - - /** - * Checks that main/common options are all printed and are consistent. - */ - @Test - public void testMainOptionsConsistent() { - ComponentInstaller.initCommands(); - discoverOptions(); - startCommand("Global"); - String help = ResourceBundle.getBundle( - "org.graalvm.component.installer.Bundle").getString("INFO_Usage"); - List lines = new ArrayList<>(Arrays.asList(help.split("\n"))); - while (!lines.get(0).startsWith("Common options:")) { - lines.remove(0); - } - lines.remove(0); - int index = 0; - while (index < lines.size()) { - String tl = lines.get(index).trim(); - if (tl.isEmpty()) { - break; - } - index++; - } - lines = lines.subList(0, index); - Map globs = new HashMap<>(ComponentInstaller.globalOptions); - checkOptions(lines, globs); - assertTrue("Help inconsistencies found: \n " + String.join("\n", errors), errors.isEmpty()); - } - - /** - * Checks that the main help reports all commands and all their options. - */ - @Test - public void testMainHelpConsistent() { - ComponentInstaller.initCommands(); - discoverOptions(); - startCommand("Global"); - String help = ResourceBundle.getBundle( - "org.graalvm.component.installer.Bundle").getString("INFO_Usage"); - String[] lines = help.split("\n"); - Map allCmds = new HashMap<>(ComponentInstaller.commands); - for (String l : lines) { - if (!l.startsWith("\tgu ")) { - continue; - } - int oS = l.indexOf('['); - int oE = l.indexOf(']'); - int sp = l.indexOf(' ', 4); - String cn = l.substring(4, sp); - if (cn.startsWith("<")) { - continue; - } - InstallerCommand c = allCmds.remove(cn); - if (c == null) { - Assert.fail("Unknown command: " + cn); - } - startCommand(cn); - if (oS == -1 || oE == -1) { - continue; - } - Map cmdOptions = new HashMap<>(c.supportedOptions()); - String optString = l.substring(oS + 1, oE); - if (optString.startsWith("-")) { - optString = optString.substring(1); - } else { - optString = ""; - } - for (int a = 0; a < optString.length(); a++) { - char o = optString.charAt(a); - String s = String.valueOf(o); - if (cmdOptions.remove(s) == null) { - if (!ComponentInstaller.globalOptions.containsKey(s)) { - reportOption(s); - } - } - } - if (message.length() > 0) { - Assert.fail("Options do not exist: " + message.toString()); - } - for (String s : new ArrayList<>(cmdOptions.keySet())) { - if (s.length() > 1 || "X".equals(cmdOptions.get(s)) || deprecatedOptions.contains(s)) { - cmdOptions.remove(s); - } - } - for (String s : cmdOptions.keySet()) { - reportOption(s); - } - if (message.length() > 0) { - Assert.fail("Options not documented: " + message.toString()); - } - } - // filter out "system" commands - for (Iterator it = allCmds.keySet().iterator(); it.hasNext();) { - String cmd = it.next(); - if (cmd.startsWith("#")) { - it.remove(); - } - } - // exclusion: update is not mentioned on main page: - allCmds.remove("update"); - if (!allCmds.isEmpty()) { - Assert.fail("Not all commands documented: " + allCmds); - } - } - - List helpLines = new ArrayList<>(); - Set deprecatedOptions = new HashSet<>(); - Set allOptions = new HashSet<>(); - - private void discoverOptions() { - try { - Field[] flds = Commands.class.getFields(); - for (Field f : flds) { - if (f.getType() != String.class) { - continue; - } - if (!(f.getName().startsWith("OPTION_") || f.getName().startsWith("LONG_OPTION_"))) { - continue; - } - String v = (String) f.get(null); - allOptions.add(v); - if (f.getAnnotation(Deprecated.class) != null) { - deprecatedOptions.add(v); - } - } - } catch (ReflectiveOperationException ex) { - - } - } - - List errors = new ArrayList<>(); - - private Set checkOptions(List optionLines, Map cmdOpts) { - Set coveredOptions = new HashSet<>(); - for (int i = 0; i < optionLines.size(); i++) { - String l = optionLines.get(i).trim(); - if (l.startsWith("-")) { - String[] spl = l.split(",?\\p{Blank}"); - String shOpt = spl[0].trim().substring(1); - if (shOpt.startsWith("-")) { - shOpt = spl[0].trim(); - } else { - if (shOpt.length() != 1) { - errors.add("Command " + currentCmd + ": Invalid short option: " + shOpt); - } else { - coveredOptions.add(shOpt); - } - String def = cmdOpts.get(shOpt); - if (def == null) { - def = ComponentInstaller.globalOptions.get(shOpt); - } - if (def == null) { - errors.add("Command " + currentCmd + ": Unsupported option: " + shOpt); - } else if (deprecatedOptions.contains(shOpt) || def.startsWith("=")) { - errors.add("Command " + currentCmd + ": Deperecated option: " + shOpt); - continue; - } - - if (spl.length == 1) { - errors.add("Command " + currentCmd + ": No explanation for: " + shOpt); - continue; - } - shOpt = spl[1].trim(); - } - if (shOpt.startsWith("--")) { - if (spl.length == 2) { - errors.add("Command " + currentCmd + ": No explanation for: " + shOpt); - continue; - } - String longOption = shOpt.substring(2); - if (longOption.length() < 2) { - errors.add("Command " + currentCmd + ": Long option too short: " + longOption); - } else { - coveredOptions.add(longOption); - } - String shopt = cmdOpts.get(longOption); - if (shopt == null) { - shopt = ComponentInstaller.globalOptions.get(longOption); - } - if (shopt == null) { - errors.add("Command " + currentCmd + ": Long option not found: " + longOption); - } else if (!(cmdOpts.containsKey(shopt) || ComponentInstaller.globalOptions.containsKey(shopt))) { - errors.add("Command " + currentCmd + ": Long option mapped to bad char: " + longOption); - } else if (Character.isLetterOrDigit(shopt.charAt(0))) { - if (!l.startsWith("-" + shopt)) { - errors.add("Command " + currentCmd + ": Long option with bad short option: " + longOption); - } - } - } - } - } - List a = new ArrayList<>(cmdOpts.keySet()); - Collections.sort(a, Collections.reverseOrder()); - - for (String s : a) { - String r = cmdOpts.get(s); - if (s.length() > 1) { - r = cmdOpts.get(r); - } - if ("X".equals(r)) { - cmdOpts.remove(s); - } - } - cmdOpts.keySet().removeAll(coveredOptions); - cmdOpts.keySet().removeAll(deprecatedOptions); - for (String s : new ArrayList<>(cmdOpts.keySet())) { - if (!Character.isLetterOrDigit(s.charAt(0))) { - cmdOpts.remove(s); - } - } - if (!cmdOpts.isEmpty()) { - errors.add("Command " + currentCmd + ": Option(s) missing in option list - " + cmdOpts.keySet()); - } - return coveredOptions; - } - - private void checkCommandAndOptionsList(InstallerCommand cmd) { - boolean overviewFound = false; - String prefix = "gu " + currentCmd + " "; - List optionLines = new ArrayList<>(); - boolean optionBlockStarted = false; - Set optionsInOverview = new HashSet<>(); - - Map cmdOpts = new HashMap<>(cmd.supportedOptions()); - cmdOpts.remove(Commands.DO_NOT_PROCESS_OPTIONS); - - Map opts = new HashMap<>(cmdOpts); - for (String l : helpLines) { - if (l.startsWith(prefix)) { - if (overviewFound) { - errors.add("Command " + currentCmd + ": Duplicate overviews not permitted"); - } - int optsStart = l.indexOf('['); - int optsEnd = l.indexOf(']'); - - if (optsStart == -1) { - if (!opts.isEmpty()) { - errors.add("Command " + currentCmd + ": Options block missing"); - } - continue; - } - if (optsEnd <= optsStart + 1) { - errors.add("Command " + currentCmd + ": Options block malformed"); - } - - String optList = l.substring(optsStart + 1, optsEnd); - if (optList.startsWith("-")) { - optList = optList.substring(1); - } - - for (int i = 0; i < optList.length(); i++) { - String o = optList.substring(i, i + 1); - - if ("X".equals(opts.get(o))) { - errors.add("Command " + currentCmd + ": Disabled option listed - " + o); - } - - if (!(opts.containsKey(o) || ComponentInstaller.globalOptions.containsKey(o))) { - errors.add("Command " + currentCmd + ": Unsupported option listed - " + o); - } - opts.remove(o); - optionsInOverview.add(o); - } - - List oneChars = opts.keySet().stream().filter((s) -> s.length() == 1 // one-liner - && !"X".equals(opts.get(s)) // not disabled - && (s.length() > 1 || Character.isLetterOrDigit(s.charAt(0))) && !deprecatedOptions.contains(s) // not - // deprecated - ).sorted().collect(Collectors.toList()); - if (!oneChars.isEmpty()) { - errors.add("Command " + currentCmd + ": Option(s) missing in command overview - " + oneChars); - } - overviewFound = true; - } - - if (l.toLowerCase().endsWith("options:")) { - optionBlockStarted = true; - } - if (optionBlockStarted) { - if (l.trim().startsWith("-")) { - optionLines.add(l.substring(l.indexOf('-'))); - } - } - } - if (!overviewFound) { - errors.add("Command " + currentCmd + ": Overview line not found"); - } - checkOptions(optionLines, cmdOpts); - } - - @Test - public void testCommandHelpConsistent() throws Exception { - discoverOptions(); - - ComponentInstaller.initCommands(); - Map allCmds = new HashMap<>(ComponentInstaller.commands); - - delegateFeedback(new FeedbackAdapter() { - @Override - public void output(String bundleKey, Object... params) { - super.output(bundleKey, params); - helpLines.addAll(Arrays.asList(reallyl10n(bundleKey, params).split("\n"))); - } - - @Override - public void message(String bundleKey, Object... params) { - output(bundleKey, params); - } - - }); - options.put(Commands.OPTION_HELP, ""); - for (String cmd : allCmds.keySet()) { - if (cmd.startsWith("#")) { - continue; - } - // exception: rebuild-images delegates help to others: - if ("rebuild-images".equals(cmd)) { - continue; - } - - InstallerCommand cc = allCmds.get(cmd); - helpLines.clear(); - cc.init(this, this.withBundle(cc.getClass())); - startCommand(cmd); - cc.execute(); - checkCommandAndOptionsList(cc); - } - assertTrue("Help inconsistencies found: \n " + String.join("\n", errors), errors.isEmpty()); - } - - private InstallerExecHelper helper = new InstallerExecHelper(); - - @Test - public void testFindGraalVMHome() throws Exception { - System.getProperties().remove(CommonConstants.ENV_GRAALVM_HOME_DEV); - - ComponentInstaller installer = new ComponentInstaller(new String[]{}); - - Path relComps = Paths.get("lib/installer/components"); - Path graal = targetPath.resolve("ggg"); - Path invalidBase = targetPath.resolve("invalid"); - Files.createDirectories(graal.resolve(relComps)); - Files.write(graal.resolve("release"), Arrays.asList("Hello, GraalVM!")); - - Environment env = helper.createFakedEnv(); - installer.setInput(env); - - Path result; - helper.fakeEnv.put(CommonConstants.ENV_GRAALVM_HOME_DEV, graal.toString()); - try { - result = installer.findGraalHome(); - fail("Should fail, invalid way to provide home."); - } catch (FailedOperationException ex) { - // expected - } - - System.setProperty(CommonConstants.ENV_GRAALVM_HOME_DEV, invalidBase.toString()); - try { - result = installer.findGraalHome(); - fail("Should fail, invalid home provided."); - } catch (FailedOperationException ex) { - // expected - } - - System.setProperty(CommonConstants.ENV_GRAALVM_HOME_DEV, graal.toString()); - result = installer.findGraalHome(); - assertTrue(Files.isSameFile(graal, result)); - } - - @Test - public void testAutoFindGraalVMHome() throws Exception { - System.getProperties().remove(CommonConstants.ENV_GRAALVM_HOME_DEV); - - // Undefine all, and use last resort: copy the JAR - URL locInstaller = getClassLocation(ComponentInstaller.class); - URL locTest = getClassLocation(ComponentInstallerTest.class); - - Assume.assumeFalse("Skipped because runs from classes", locInstaller == null || locTest == null); - - Path origInstaller = new File(locInstaller.toURI()).toPath(); - Path origTest = new File(locTest.toURI()).toPath(); - - Assume.assumeTrue("Skipped because runs from classes", - origInstaller != null && origTest != null && - Files.isRegularFile(origInstaller) && Files.isRegularFile(origTest)); - - Path relComps = Paths.get("lib/installer/components"); - Path graal = targetPath.resolve("ggg"); - Path instDir = graal.resolve("lib/installer"); - Files.createDirectories(graal.resolve(relComps)); - Files.write(graal.resolve("release"), Arrays.asList("Hello, GraalVM!")); - - // copy over the JARs: - Path targetInstaller = instDir.resolve(origInstaller.getFileName()); - Path targetTest = instDir.resolve(origTest.getFileName()); - Files.copy(origInstaller, targetInstaller); - Files.copy(origTest, targetTest); - - List urls = new ArrayList<>(); - - urls.add(targetInstaller.toUri().toURL()); - urls.add(targetTest.toUri().toURL()); - - Stream urlStream; - if (getClass().getClassLoader() instanceof URLClassLoader) { - URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader(); - urlStream = Arrays.stream(myLoader.getURLs()); - } else { - urlStream = Arrays.stream(System.getProperty("java.class.path").split(System.getProperty("path.separator"))).map(e -> { - try { - return Paths.get(e).toUri().toURL(); - } catch (MalformedURLException ex) { - } - return null; - }).filter(u -> u != null); - } - urlStream.filter(u -> !(locInstaller.equals(u) || locTest.equals(u))).collect(Collectors.toCollection(() -> urls)); - - URLClassLoader ldr = new URLClassLoader( - urls.toArray(new URL[urls.size()]), - getClass().getClassLoader().getParent()); - - Class testClazz = Class.forName(InstallerExecHelper.class.getName(), true, ldr); - - Object inst = testClazz.getDeclaredConstructor().newInstance(); - Method m = testClazz.getMethod("performGraalVMHomeAutodetection"); - String res = (String) m.invoke(inst); - - assertEquals(graal.toString(), res); - } - - public static class InstallerExecHelper { - Map fakeEnv = new HashMap<>(System.getenv()); - - private Environment createFakedEnv() { - Environment env = new Environment("", Collections.emptyList(), Collections.emptyMap()) { - @Override - public String getParameter(String key, boolean cmdLine) { - if (cmdLine) { - return super.getParameter(key, cmdLine); - } else { - return fakeEnv.get(key); - } - } - - }; - return env; - } - - public String performGraalVMHomeAutodetection() { - ComponentInstaller installer = new ComponentInstaller(new String[]{}); - fakeEnv.clear(); - Environment env = createFakedEnv(); - installer.setInput(env); - - installer.findGraalHome(); - return installer.getGraalHomePath().toString(); - } - } - - private static URL getClassLocation(Class clazz) { - ProtectionDomain pd = clazz.getProtectionDomain(); - if (pd != null) { - CodeSource cs = pd.getCodeSource(); - if (cs != null) { - return cs.getLocation(); - } - } - return null; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DirectoryArchiveReader.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DirectoryArchiveReader.java deleted file mode 100644 index fce07a683cf9..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DirectoryArchiveReader.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.graalvm.component.installer.persist.DirectoryMetaLoader; -import org.graalvm.component.installer.persist.MetadataLoader; - -/** - * - * @author sdedic - */ -public class DirectoryArchiveReader implements ComponentArchiveReader { - @Override - public MetadataLoader createLoader(Path p, byte[] fileStart, String serial, Feedback feedback, boolean verify) throws IOException { - if (!Files.isDirectory(p)) { - return null; - } - if (Files.isReadable(p.resolve("META-INF/MANIFEST.MF"))) { - return DirectoryMetaLoader.create(p, feedback); - } else { - return null; - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DownloadURLIterableTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DownloadURLIterableTest.java deleted file mode 100644 index 2a5ccd2ef3c0..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/DownloadURLIterableTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.Iterator; -import org.graalvm.component.installer.jar.JarArchive; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; - -public class DownloadURLIterableTest extends CommandTestBase { - @Rule public final ProxyResource proxyResource = new ProxyResource(); - - @Test - public void testConstructComponentParam() throws Exception { - initURLComponent("persist/data/truffleruby2.jar", "test://graalvm.io/download/truffleruby.zip"); - assertEquals("test://graalvm.io/download/truffleruby.zip", param.getSpecification()); - assertEquals("test://graalvm.io/download/truffleruby.zip", param.getDisplayName()); - assertFalse(param.isComplete()); - assertFalse(Handler.isVisited(url)); - } - - @Test - public void testURLParameter() throws Exception { - initURLComponent("persist/data/truffleruby3.jar", "test://graalvm.io/download/truffleruby.zip"); - this.textParams.add("test://graalvm.io/download/truffleruby.zip"); - - DownloadURLIterable iterable = new DownloadURLIterable(this, this); - Iterator it = iterable.iterator(); - assertTrue(it.hasNext()); - - ComponentParam p = it.next(); - - assertEquals("test://graalvm.io/download/truffleruby.zip", p.getSpecification()); - MetadataLoader ldr = p.createMetaLoader(); - assertFalse(p.isComplete()); - - ComponentInfo ci = ldr.getComponentInfo(); - assertTrue(p.isComplete()); - - assertEquals("ruby", ci.getId()); - assertEquals("0.33-dev", ci.getVersionString()); - - JarArchive jf = (JarArchive) ldr.getArchive(); - Archive.FileEntry je = jf.getJarEntry("META-INF/MANIFEST.MF"); - assertNotNull(je); - jf.close(); - } - - @Test - public void testMalformedURL() throws Exception { - this.textParams.add("testx://graalvm.io/download/truffleruby.zip"); - - DownloadURLIterable iterable = new DownloadURLIterable(this, this); - Iterator it = iterable.iterator(); - assertTrue(it.hasNext()); - - exception.expect(FailedOperationException.class); - exception.expectMessage("URL_InvalidDownloadURL"); - - it.next(); - } - - @Test - public void testInstallFromURL() throws Exception { - initURLComponent("persist/data/truffleruby2.jar", "test://graalvm.io/download/truffleruby.zip"); - - components.add(rparam); - - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/EnvironmentTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/EnvironmentTest.java deleted file mode 100644 index 852086122137..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/EnvironmentTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.net.MalformedURLException; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.stream.Collectors; -import org.junit.AfterClass; -import org.junit.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * Tests basic functionality of the Environment class. - * - * @author sdedic - */ -public class EnvironmentTest { - @Rule public ExpectedException exception = ExpectedException.none(); - - private static ResourceBundle B1; - private static Locale saveLocale; - private Environment env; - - private Map initOptions = new HashMap<>(); - - @BeforeClass - public static void setUp() { - // establish well-known locale, so we may check I18ned strings - saveLocale = Locale.getDefault(); - Locale.setDefault(Locale.US); - B1 = ResourceBundle.getBundle("org.graalvm.component.installer.Bundle", Locale.US); - } - - @AfterClass - public static void tearDown() { - Locale.setDefault(saveLocale); - } - - class FailInputStream extends FilterInputStream { - FailInputStream() { - super(System.in); - } - - @Override - public int read() throws IOException { - Assert.fail("Unexpected read"); - return super.read(); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - Assert.fail("Unexpected read"); - return super.read(b, off, len); - } - } - - ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(); - ByteArrayOutputStream errBuffer = new ByteArrayOutputStream(); - - @Test - public void testNonInteractiveLineFails() { - setupEmptyEnv(); - env.setNonInteractive(true); - env.setIn(new FailInputStream()); - exception.expect(NonInteractiveException.class); - assertNull(env.acceptLine(false)); - } - - /** - * Non-interactive mode + auto-yes, and confirmation line. Should succeed. - */ - @Test - public void testNonInteractiveYesLineOK() { - setupEmptyEnv(); - env.setNonInteractive(true); - env.setAutoYesEnabled(true); - env.setIn(new FailInputStream()); - assertSame(Feedback.AUTO_YES, env.acceptLine(true)); - } - - /** - * Non-interactive mode + auto-yes, but regular, not a confirmation line. Should fail. - */ - @Test - public void testNonInteractiveNormalLineFails() { - setupEmptyEnv(); - env.setNonInteractive(true); - env.setAutoYesEnabled(true); - env.setIn(new FailInputStream()); - exception.expect(NonInteractiveException.class); - exception.expectMessage(B1.getString("ERROR_NoninteractiveInput")); - assertSame(Feedback.AUTO_YES, env.acceptLine(false)); - } - - /** - * Regular + auto-yes. Confirmation line should not read the input. - */ - @Test - public void testAutoConfirmSkipsInput() { - setupEmptyEnv(); - env.setAutoYesEnabled(true); - env.setIn(new FailInputStream()); - assertSame(Feedback.AUTO_YES, env.acceptLine(true)); - } - - @Test - public void testNonInteractivePasswordFails() { - setupEmptyEnv(); - env.setNonInteractive(true); - env.setIn(new FailInputStream()); - exception.expect(NonInteractiveException.class); - assertNull(env.acceptPassword()); - } - - void setupEmptyEnv() { - List parameters = Arrays.asList("param"); - env = new Environment("test", "org.graalvm.component.installer", parameters, initOptions); - } - - private static String readLines(byte[] arr) throws IOException { - try (BufferedReader bfr = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(arr)))) { - return bfr.lines().map(l -> l + "\n").collect(Collectors.joining()); - } - } - - /** - * Checks that an error will be printed without stacktrace. - */ - @Test - public void testErrorMessagePlain() throws Exception { - setupEmptyEnv(); - env.setErr(new PrintStream(errBuffer)); - env.error("ERROR_UserInput", new ClassCastException(), "Foobar"); - // Windows compat: CRLF -> LF conversion - String s = readLines(errBuffer.toByteArray()); - assertEquals(B1.getString("ERROR_UserInput").replace("{0}", "Foobar") + "\n", s); - } - - /** - * Checks that an error will be printed together with the stacktrace. - */ - @Test - public void testErrorMessageWithException() throws Exception { - initOptions.put(Commands.OPTION_DEBUG, ""); - setupEmptyEnv(); - env.setErr(new PrintStream(errBuffer)); - env.error("ERROR_UserInput", new ClassCastException(), "Foobar"); - // Windows compat: CRLF -> LF conversion - String all = readLines(errBuffer.toByteArray()); - String[] lines = all.split("\n"); - assertEquals(B1.getString("ERROR_UserInput").replace("{0}", "Foobar"), lines[0]); - assertTrue(lines[1].contains("ClassCastException")); - } - - @Test - public void testFailureOperation() throws Exception { - setupEmptyEnv(); - - Throwable t = env.failure("URL_InvalidDownloadURL", new MalformedURLException("Foo"), "Bar", "Baz"); - assertTrue(t instanceof FailedOperationException); - String s = MessageFormat.format(B1.getString("URL_InvalidDownloadURL"), "Bar", "Baz"); - assertEquals(t.getLocalizedMessage(), s); - assertNotSame(t, t.getCause()); - assertEquals("Foo", t.getCause().getLocalizedMessage()); - } - - @Test - public void testOutput() throws Exception { - setupEmptyEnv(); - - env.setOut(new PrintStream(outBuffer)); - env.output("ERROR_MissingCommand"); - // Windows compat: CRLF -> LF conversion - String s = readLines(outBuffer.toByteArray()); - assertEquals(B1.getString("ERROR_MissingCommand") + "\n", s); - } - - @Test - public void testSilentOutput() throws Exception { - setupEmptyEnv(); - assertFalse(env.setSilent(true)); - - // output error even when silent - env.setErr(new PrintStream(errBuffer)); - env.error("ERROR_UserInput", new ClassCastException(), "Foobar"); - // Windows compat: CRLF -> LF conversion - String s = readLines(errBuffer.toByteArray()); - assertEquals(B1.getString("ERROR_UserInput").replace("{0}", "Foobar") + "\n", s); - - // don't output normal output when silent - env.setOut(new PrintStream(outBuffer)); - env.output("ERROR_MissingCommand"); - // Windows compat: CRLF -> LF conversion - s = readLines(outBuffer.toByteArray()); - assertEquals("", s); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/InstallerCommandlineTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/InstallerCommandlineTest.java deleted file mode 100644 index 7b25301cdf8c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/InstallerCommandlineTest.java +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.net.URL; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class InstallerCommandlineTest extends CommandTestBase { - - static class MainErrorException extends RuntimeException { - private static final long serialVersionUID = 0L; - } - - private Environment environment; - - class MockInstallerMain extends ComponentInstaller { - MockInstallerMain(String[] args) { - super(args); - initGlobalOptions(); - } - - @Override - protected Environment setupEnvironment(SimpleGetopt go) { - - Environment env = new Environment(getCommand(), getParameters(), go.getOptValues()) { - @Override - public Map parameters(boolean cmdLine) { - return InstallerCommandlineTest.this.parameters(cmdLine); - } - - @Override - public String getParameter(String key, boolean cmdLine) { - return InstallerCommandlineTest.this.getParameter(key, cmdLine); - } - - }; - - setInput(env); - setFeedback(InstallerCommandlineTest.this); - env.setGraalHome(exposeGraalHomePath()); - env.setLocalRegistry(getLocalRegistry()); - env.setFileOperations(getFileOperations()); - environment = env; - return env; - } - - @Override - protected RuntimeException error(String messageKey, Object... aa) { - InstallerCommandlineTest.this.error(messageKey, null, aa); - throw new MainErrorException(); - } - - @Override - protected SimpleGetopt createOptionsObject(Map opts) { - return new SimpleGetopt(globalOptions) { - @Override - public RuntimeException err(String messageKey, Object... aa) { - return MockInstallerMain.this.error(messageKey, aa); - } - }; - } - - @Override - protected void printUsage(Feedback output) { - super.printUsage(InstallerCommandlineTest.this); - } - } - - Path exposeGraalHomePath() { - return getGraalHomePath(); - } - - MockInstallerMain main = new MockInstallerMain(new String[0]); - - static class Msg { - String keyOrMessage; - Object[] args; - Throwable ex; - - Msg(String keyOrMessage, Object[] args, Throwable ex) { - this.keyOrMessage = keyOrMessage; - this.args = args; - this.ex = ex; - } - } - - class CaptureOut extends FeedbackAdapter { - private List err = new ArrayList<>(); - private List out = new ArrayList<>(); - - @Override - public void error(String key, Throwable t, Object... params) { - err.add(new Msg(key, params, t)); - } - - @Override - public void output(String bundleKey, Object... params) { - out.add(new Msg(bundleKey, params, null)); - } - - @Override - public void message(String bundleKey, Object... params) { - out.add(new Msg(bundleKey, params, null)); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - System.err.println(""); - return false; - } - - @Override - public String l10n(String key, Object... params) { - if ("Installer_BuiltingCatalogURL".equals(key)) { - return testCatalogURL; - } - return super.l10n(key, params); - } - } - - String testCatalogURL = "test://www.graalvm.org/test/catalog"; - CaptureOut capture = new CaptureOut(); - LinkedList args = new LinkedList<>(); - - void assertMsg(String msgKey, boolean out) { - List list = out ? capture.out : capture.err; - for (Msg m : list) { - if (msgKey.equals(m.keyOrMessage)) { - return; - } - } - fail("Expected message: " + msgKey); - } - - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - ComponentInstaller.initCommands(); - ComponentInstaller.initGlobalOptions(); - delegateFeedback(capture); - } - - /** - * Checks that help is printed with no params. - */ - @Test - public void testNoParamsPrintsHelp() { - main.processOptions(new LinkedList<>(Collections.emptyList())); - assertMsg("INFO_Usage", true); - } - - /** - * Checks that help is printed with no params. - */ - @Test - public void testNoCommandPrintsError() { - args = new LinkedList<>(); - args.add("--file"); - exception.expect(MainErrorException.class); - - try { - main.processOptions(args); - } finally { - assertMsg("ERROR_MissingCommand", false); - } - } - - /** - * Checks that --version option prints version and terminates with 0 exit code. - */ - @Test - public void testVersionSucceeds() { - args = new LinkedList<>(); - args.add("--version"); - - delegateFeedback(capture); - int excode = main.processOptions(args); - assertTrue(capture.err.isEmpty()); - assertMsg("MSG_InstallerVersion", true); - assertEquals("Must complete succesfully", 0, excode); - } - - /** - * Checks that --show-version option prints version and performs the command. - */ - @Test - public void testShowVersionSucceeds() { - args = new LinkedList<>(); - args.add("--show-version"); - args.add("list"); - - delegateFeedback(capture); - int excode = main.processOptions(args); - assertTrue(capture.err.isEmpty()); - assertMsg("MSG_InstallerVersion", true); - assertEquals("Should continue execution", -1, excode); - } - - /** - * Checks that help is printed with no params. - */ - @Test - public void testHelpOption() { - args = new LinkedList<>(); - args.add("--help"); - assertNull(main.interpretOptions(main.createOptions(args))); - assertMsg("INFO_Usage", true); - - main = new MockInstallerMain(new String[0]); - capture.out.clear(); - args.add(0, "install"); - assertNotNull(main.createOptions(args)); - } - - /** - * Checks that -L -U is not valid. - */ - @Test - public void testUrlAndFiles() throws Exception { - exception.expect(MainErrorException.class); - - args.add("--url"); - args.add("--file"); - main.processOptions(args); - } - - /** - * Checks that -c -U is not valid. - */ - @Test - public void testUrlAndCatalog() throws Exception { - exception.expect(MainErrorException.class); - - args.add("--url"); - args.add("-c"); - main.processOptions(args); - } - - /** - * Checks that -c -U is not valid. - */ - @Test - public void testUrlAndCustomCatalog() throws Exception { - exception.expect(MainErrorException.class); - - args.add("--url"); - args.add("-C"); - args.add("eee"); - main.processOptions(args); - } - - @Rule public ProxyResource proxyResource = new ProxyResource(); - - @Override - public CatalogFactory getCatalogFactory() { - return environment.getCatalogFactory(); - } - - /** - * Checks that the hardcoded catalog is used, if there's nothing in release file. - */ - @Test - public void testUseHardcodedCatalog() throws Exception { - URL u = getClass().getResource("remote/catalog"); - Handler.bind(testCatalogURL, u); - this.storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev"); - args.add("avail"); - - main.processOptions(args); - main.doProcessCommand(); - assertTrue(Handler.isVisited(testCatalogURL)); - } - - String releaseURL = "test://graalvm.org/relase/catalog"; - - void setupReleaseCatalog() { - this.storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev"); - this.storage.graalInfo.put("component_catalog", releaseURL); - } - - /** - * Checks that the hardcoded catalog is used, if there's nothing in release file. - */ - @Test - public void testUseReleaseCatalog() throws Exception { - setupReleaseCatalog(); - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - args.add("avail"); - - main.processOptions(args); - main.doProcessCommand(); - assertTrue(Handler.isVisited(releaseURL)); - } - - String envURL = "test://graalvm.org/environment/catalog"; - - void setupEnvCatalog() { - envParameters.put("GRAALVM_CATALOG", envURL); - } - - /** - * Checks that the hardcoded catalog is used, if there's nothing in release file. - */ - @Test - public void testEnvironmentOverridesRelease() throws Exception { - URL u = getClass().getResource("remote/catalog"); - Handler.bind(envURL, u); - setupReleaseCatalog(); - setupEnvCatalog(); - args.add("avail"); - - main.processOptions(args); - main.doProcessCommand(); - assertTrue(Handler.isVisited(envURL)); - } - - String syspropURL = "test://graalvm.org/sysprop/catalog"; - - void setupSyspropCatalog() { - propParameters.put("org.graalvm.component.catalog", syspropURL); - } - - /** - * Checks that the hardcoded catalog is used, if there's nothing in release file. - */ - @Test - public void testSysPropertyOverridesEnv() throws Exception { - URL u = getClass().getResource("remote/catalog"); - Handler.bind(syspropURL, u); - setupReleaseCatalog(); - setupEnvCatalog(); - setupSyspropCatalog(); - args.add("avail"); - - main.processOptions(args); - assertEquals(0, main.doProcessCommand()); - assertTrue(Handler.isVisited(syspropURL)); - } - - /** - * Checks that without an explicit option remote catalogs are not processed when using local - * files. - */ - @Test - public void testLocalFileDoesNotReadCatalogs() throws Exception { - setupReleaseCatalog(); - Path file = dataFile("persist/dir1/llvm-toolchain.jar"); - args.add("--file"); - args.add("install"); - args.add("-0"); - args.add(file.toString()); - - main.processOptions(args); - assertEquals(0, main.doProcessCommand()); - - assertFalse(Handler.isVisited(releaseURL)); - assertFalse(Handler.isVisited(envURL)); - assertFalse(Handler.isVisited(testCatalogURL)); - } - - /** - * Checks that without an explicit option remote catalogs are not processed when using local - * files. - */ - @Test - public void testLocalFilesWithDefaultCatalog() throws Exception { - setupReleaseCatalog(); - Path file = dataFile("persist/dir1/llvm-toolchain.jar"); - args.add("--file"); - args.add("-c"); - args.add("install"); - args.add("-0"); - args.add(file.toString()); - - // allow the remote catalog: - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - - main.processOptions(args); - assertEquals(0, main.doProcessCommand()); - - // no ID is resolved - assertFalse(Handler.isVisited(releaseURL)); - assertFalse(Handler.isVisited(envURL)); - assertFalse(Handler.isVisited(testCatalogURL)); - } - - /** - * Local file with dependencies fails to install if -D is not given. - */ - @Test - public void testFailLocalWithDependencies() throws Exception { - setupReleaseCatalog(); - Path file = dataFile("persist/dir1/ruby.jar"); - args.add("--file"); - args.add("install"); - args.add("-0"); - args.add(file.toString()); - - // allow the remote catalog: - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - - main.processOptions(args); - - exception.expect(FailedOperationException.class); - exception.expectMessage("INSTALL_UnresolvedDependencies"); - - try { - assertEquals(0, main.doProcessCommand()); - } finally { - assertFalse(Handler.isVisited(releaseURL)); - assertFalse(Handler.isVisited(envURL)); - assertFalse(Handler.isVisited(testCatalogURL)); - } - } - - /** - * Checks that with -D, local dependencies are resolved in the file's directory. - */ - @Test - public void testLocalDepsResolvedInDirectory() throws Exception { - setupReleaseCatalog(); - Path file = dataFile("persist/dir1/ruby.jar"); - args.add("--file"); - args.add("install"); - args.add("-0"); - args.add("-D"); - args.add(file.toString()); - - // allow the remote catalog: - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - - main.processOptions(args); - - assertEquals(0, main.doProcessCommand()); - assertFalse(Handler.isVisited(releaseURL)); - assertFalse(Handler.isVisited(envURL)); - assertFalse(Handler.isVisited(testCatalogURL)); - } - - /** - * Checks that -c will cause the catalog to be downloaded. - * - * @throws Exception - */ - @Test - public void testEnableCatalogFetchesRemote() throws Exception { - setupReleaseCatalog(); - args.add("-c"); - args.add("list"); - - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - storage.graalInfo.put("component_catalog", releaseURL); - - main.processOptions(args); - main.doProcessCommand(); - - assertTrue(Handler.isVisited(releaseURL)); - } - - /** - * When -C local-file is passed, gu must not touch its builtin (release file) catalogs URLs. - * - * @throws Exception - */ - @Test - public void testDirectoryCatalogDisablesRelease() throws Exception { - setupReleaseCatalog(); - Path dir = dataFile("repo/19.3.0.0"); - args.add("-C"); - args.add(dir.toAbsolutePath().toString()); - args.add("avail"); - args.add("--show-updates"); - - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - storage.graalInfo.put("component_catalog", releaseURL); - - Set componentShorts = new HashSet<>(); - class FB extends FeedbackAdapter { - - @Override - public String l10n(String key, Object... params) { - if ("LIST_ComponentShortList".equals(key)) { - return "%1$s"; - } - return super.l10n(key, params); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - componentShorts.add(msg); - return super.verbatimOut(msg, beVerbose); - } - } - - FB fb = new FB(); - - delegateFeedback(fb); - - main.processOptions(args); - main.doProcessCommand(); - - assertTrue(componentShorts.contains("graalvm")); - assertTrue(componentShorts.contains("R")); - assertTrue(componentShorts.contains("ruby")); - assertTrue(componentShorts.contains("llvm-toolchain")); - - assertFalse(Handler.isVisited(releaseURL)); - } - - /** - * There's a mix of component versions in the dir; should return just the ones that fit into the - * graalvm. - * - * @throws Exception - */ - @Test - public void testVersionSpecificComponentsFromDir() throws Exception { - setupReleaseCatalog(); - Path dir = dataFile("persist/data"); - args.add("-C"); - args.add(dir.toAbsolutePath().toString()); - args.add("avail"); - args.add("--show-updates"); - - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - storage.graalInfo.put("component_catalog", releaseURL); - - Set componentShorts = new HashSet<>(); - class FB extends FeedbackAdapter { - - @Override - public String l10n(String key, Object... params) { - if ("LIST_ComponentShortList".equals(key)) { - return "%1$s"; - } - return super.l10n(key, params); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - componentShorts.add(msg); - return super.verbatimOut(msg, beVerbose); - } - } - - FB fb = new FB(); - - delegateFeedback(fb); - - main.processOptions(args); - main.doProcessCommand(); - - // note: there's a typo in test data. - assertTrue(componentShorts.contains("org.graavm.ruby")); - // llvm-toolchain requires graalvm 0.32, which is not compatible with 0.33 - assertTrue(componentShorts.contains("ruby")); - - assertFalse(Handler.isVisited(releaseURL)); - } - - /** - * Checks that potential missing resources in release catalog are skipped. - */ - @Test - public void testSkipMissingResourcesInReleaseCatalog() throws Exception { - setupReleaseCatalog(); - args.add("avail"); - - URL u = getClass().getResource("remote/catalog.properties"); - String urlString = releaseURL + "_2"; - Handler.bind(urlString, u); - // note: the releaseURL is NOT bound, FileNotFoundException will be thrown - storage.graalInfo.put("component_catalog", releaseURL + "|" + urlString); - - class FB extends FeedbackAdapter { - String warningLine; - - @Override - public void error(String key, Throwable t, Object... params) { - if ("REMOTE_WarningErrorDownloadCatalogNotFoundSkip".equals(key)) { - warningLine = params[0].toString(); - } - } - - } - - FB fb = new FB(); - - delegateFeedback(fb); - main.processOptions(args); - main.doProcessCommand(); - - assertTrue(Handler.isVisited(releaseURL)); - assertTrue(Handler.isVisited(urlString)); - assertEquals(releaseURL, fb.warningLine); - } - - /** - * Checks that catalog entries in environment win over release file ones. - * - * @throws Exception - */ - @Test - public void testExplicitCatalogWinsOverItems() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.1.0"); - storage.graalInfo.put("component_catalog", releaseURL); - - // override with env variables catalog entries: - String url1 = "test://graalv.org/test/explicit.properties"; - String url2 = "test://graalv.org/test/envcatalog.properties"; - envParameters.put("GRAALVM_CATALOG", url1); - envParameters.put("GRAALVM_COMPONENT_CATALOG_1_URL", url2); - envParameters.put("GRAALVM_COMPONENT_CATALOG_1_LABEL", "First env"); - - args.add("avail"); - - main.processOptions(args); - main.doProcessCommand(); - - URL u = getClass().getResource("remote/catalog"); - Handler.bind(releaseURL, u); - Handler.bind(url1, u); - Handler.bind(url2, u); - - assertFalse(Handler.isVisited(releaseURL)); - assertFalse(Handler.isVisited(url2)); - - assertTrue(Handler.isVisited(url1)); - } - - /** - * By default, the default edition must be used to determine the catalogs. - * - * @throws Exception - */ - @Test - public void testUseDefaultEditionCatalogsSingle() throws Exception { - String url0 = "test://graalvm.org/relase/catalog2"; - String url1 = "test://graalv.org/test/explicit.properties"; - String url2 = "test://graalv.org/test/envcatalog.properties"; - - releaseURL = url0 + "|{ee=GraalVM EE}" + url1; // NOI18N - storage.graalInfo.put(CommonConstants.RELEASE_CATALOG_KEY, releaseURL); - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.1.0"); - - URL u = getClass().getResource("remote/catalog"); - Handler.bind(url0, u); - Handler.bind(url1, u); - Handler.bind(url2, u); - - args.add("avail"); - - main.processOptions(args); - main.doProcessCommand(); - - assertTrue(Handler.isVisited(url0)); - assertFalse(Handler.isVisited(url1)); - assertFalse(Handler.isVisited(url2)); - } - - @Test - public void testUseExplicitEditionOnParams() throws Exception { - String url0 = "test://graalvm.org/relase/catalog2"; - String url1 = "test://graalv.org/test/explicit.properties"; - String url2 = "test://graalv.org/test/envcatalog.properties"; - - releaseURL = url0 + "|{ee=GraalVM EE}" + url1; // NOI18N - storage.graalInfo.put(CommonConstants.RELEASE_CATALOG_KEY, releaseURL); - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.1.0"); - - URL u = getClass().getResource("remote/catalog"); - Handler.bind(url0, u); - Handler.bind(url1, u); - Handler.bind(url2, u); - - args.add("avail"); - args.add("--edition"); - args.add("ee"); - - main.processOptions(args); - main.doProcessCommand(); - - assertFalse(Handler.isVisited(url0)); - assertTrue(Handler.isVisited(url1)); - assertFalse(Handler.isVisited(url2)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MemoryFeedback.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MemoryFeedback.java deleted file mode 100644 index dd0d5d4037c3..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MemoryFeedback.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import static org.junit.Assert.assertEquals; -import java.net.URL; -import java.nio.file.Path; -import java.util.ArrayDeque; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import org.graalvm.component.installer.MemoryFeedback.Memory; - -/** - * - * @author odouda - */ -public final class MemoryFeedback implements Feedback, Iterable { - - @Override - public Iterator iterator() { - return new Iterator<>() { - final Queue mems = new ArrayDeque<>(mem); - - @Override - public boolean hasNext() { - return !mems.isEmpty(); - } - - @Override - public Memory next() { - return mems.poll(); - } - }; - } - - @Override - public void addLocalResponseHeadersCache(URL location, Map> local) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Map> getLocalResponseHeadersCache(URL location) { - throw new UnsupportedOperationException("Not supported yet."); - } - - public enum Case { - ERR("Error"), - FLR("Failure"), - MSG("Message"), - FRM("Format"), - INP("Input"); - - final String msg; - - Case(String msg) { - this.msg = msg; - } - - @Override - public String toString() { - return msg; - } - - } - - final Queue mem = new ArrayDeque<>(); - boolean verb = true; - boolean silent = false; - private Queue> lineAccept = new ArrayDeque<>(); - - public void nextInput(String input) { - lineAccept.add((m) -> input); - } - - public final class Memory { - - public final boolean silent; - public final Case cas; - public final String key; - public final Object[] params; - public final Throwable t; - - Memory(final Case cas, final String key, final Object[] params, Throwable t) { - this.key = key; - this.params = params; - this.cas = cas; - this.t = t; - this.silent = MemoryFeedback.this.silent; - } - - Memory(final Case cas, final String key, final Object[] params) { - this(cas, key, params, null); - } - - Memory(String response) { - this(Case.INP, response, new Object[0]); - } - - @Override - public String toString() { - return cas + ": " + key + ": " + Arrays.toString(params) + (t == null ? "" : ": " + t.getClass()) + "; silent=" + this.silent; - } - } - - public boolean isEmpty() { - return mem.isEmpty(); - } - - public int size() { - return mem.size(); - } - - private static void assEq(Object exp, Object obj, Supplier msg) { - try { - assertEquals(exp, obj); - } catch (AssertionError ae) { - throw new AssertionError(msg.get() + " " + ae.getLocalizedMessage()); - } - } - - private static Supplier form(String format, Object... args) { - return () -> String.format(format, args); - } - - private static final String CASE = "Feedback type."; - private static final String KEY = "Feedback type:\"%s\" key."; - private static final String FEEDBACK = "Feedback type:\"%s\" key:\"%s\""; - - public Memory checkMem(Case cas, String key) { - return checkMem(cas, key, true); - } - - private Memory checkMem(Case cas, String key, boolean paramCheck) { - Memory m = mem.poll(); - assert m != null : "There was no Feedback memory to check."; - assertEquals(CASE, cas, m.cas); - assEq(key, m.key, form(KEY, cas)); - if (paramCheck && m.params.length > 0) { - System.out.printf("Unchecked Feedback parameters:\n\t" + FEEDBACK + "\n\tParameters: %s\n", cas, key, Arrays.toString(m.params)); - } - return m; - } - - private static final String PARAMS_LENGTH = FEEDBACK + " parameter count."; - private static final String PARAM = FEEDBACK + " parameter."; - - public Memory checkMem(Case cas, String key, Object... params) { - Memory m = checkMem(cas, key, false); - assEq(params.length, m.params.length, form(PARAMS_LENGTH, cas, key)); - for (int i = 0; i < params.length; ++i) { - assEq(params[i], m.params[i], form(PARAM, cas, key)); - } - return m; - } - - @Override - public void error(String key, Throwable t, Object... params) { - mem.add(new Memory(Case.ERR, key, params, t)); - } - - @Override - public RuntimeException failure(String key, Throwable t, Object... params) { - mem.add(new Memory(Case.FLR, key, params, t)); - return null; - } - - @Override - public String l10n(String key, Object... params) { - mem.add(new Memory(Case.FRM, key, params)); - return null; - } - - @Override - public void message(String bundleKey, Object... params) { - mem.add(new Memory(Case.MSG, bundleKey, params)); - } - - @Override - public void output(String bundleKey, Object... params) { - mem.add(new Memory(Case.MSG, bundleKey, params)); - } - - @Override - public void outputPart(String bundleKey, Object... params) { - mem.add(new Memory(Case.MSG, bundleKey, params)); - } - - @Override - public String toString() { - return "Feedback memory dump:\n\t" + mem.stream().sequential().map(m -> m.toString()).collect(Collectors.joining("\n\t")); - } - - @Override - public boolean verbosePart(String bundleKey, Object... params) { - return verb; - } - - @Override - public boolean verboseOutput(String bundleKey, Object... params) { - return verb; - } - - @Override - public Feedback withBundle(Class clazz) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean verbatimOut(String msg, boolean verbose) { - return verbose; - } - - @Override - public boolean verbatimPart(String msg, boolean verbose) { - return verbose; - } - - @Override - public boolean verbatimPart(String msg, boolean error, boolean verbose) { - return verbose; - } - - @Override - public boolean backspace(int chars, boolean beVerbose) { - return verb; - } - - @Override - public boolean isNonInteractive() { - return verb; - } - - @Override - public String acceptLine(boolean autoYes) { - if (autoYes) { - return input(AUTO_YES); - } - Function fnc = lineAccept.poll(); - if (fnc == null) { - return input(null); - } - return input(fnc.apply(mem.peek())); - } - - private String input(String memObj) { - mem.add(new Memory(memObj)); - return memObj; - } - - @Override - public char[] acceptPassword() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void addLocalFileCache(URL location, Path local) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Path getLocalCache(URL location) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isSilent() { - return this.silent; - } - - @Override - public boolean setSilent(boolean silent) { - boolean wasSilent = this.silent; - this.silent = silent; - return wasSilent; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MockURLConnection.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MockURLConnection.java deleted file mode 100644 index 59520a8c71b3..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/MockURLConnection.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; -import java.util.List; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class MockURLConnection extends URLConnection { - private final URLConnection clu; - private final IOException theException; - - public MockURLConnection(URLConnection clu, URL url, IOException theException) { - super(url); - this.clu = clu; - this.theException = theException != null ? theException : new FileNotFoundException(); - } - - @Override - public InputStream getInputStream() throws IOException { - connect(); - return clu.getInputStream(); - } - - @Override - public String getHeaderField(int n) { - try { - connect(); - } catch (IOException ex) { - Logger.getLogger(CatalogIterableTest.class.getName()).log(Level.SEVERE, null, ex); - } - return super.getHeaderField(n); - } - - @Override - public Map> getHeaderFields() { - try { - connect(); - } catch (IOException ex) { - Logger.getLogger(CatalogIterableTest.class.getName()).log(Level.SEVERE, null, ex); - } - return super.getHeaderFields(); - } - - @Override - public void connect() throws IOException { - throw theException; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SimpleGetoptTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SimpleGetoptTest.java deleted file mode 100644 index 55ba63ac6a94..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SimpleGetoptTest.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class SimpleGetoptTest extends TestBase { - SimpleGetopt getopt; - String errorKey; - Object[] errorParams; - - @Rule public ExpectedException exception = ExpectedException.none(); - - @Before - public void setUp() { - Map g = new HashMap<>(ComponentInstaller.globalOptions); - g.put("8", "=C"); - g.put("long-user", "U"); - g.put("U", "s"); - getopt = new SimpleGetopt(g) { - @Override - public RuntimeException err(String messageKey, Object... args) { - errorKey = messageKey; - errorParams = args; - throw new FailedOperationException(messageKey); - } - }; - for (String s : ComponentInstaller.commands.keySet()) { - getopt.addCommandOptions(s, ComponentInstaller.commands.get(s).supportedOptions()); - } - } - - private void setParams(String p) { - getopt.setParameters(new LinkedList<>(Arrays.asList(p.split(" +")))); - } - - @Test - public void testMissingCommand() { - setParams(""); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_MissingCommand"); - getopt.process(); - } - - @Test - public void testUnknownCommand() { - setParams("foo"); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnknownCommand"); - getopt.process(); - } - - @Test - public void testUnknownCommandWithOptions() { - setParams("-e -v foo -h"); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnknownCommand"); - getopt.process(); - } - - @Test - public void testSpecificOptionsPrecedeCommand() { - setParams("-s info -h"); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnsupportedGlobalOption"); - getopt.process(); - } - - @Test - public void testUnknownOption() { - setParams("install -S -h"); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnsupportedOption"); - getopt.process(); - } - - @Test - public void testUnknownOptionIgnoredBecauseOfHelp() { - setParams("install -h -s"); - getopt.process(); - - assertNotNull(getopt.getOptValues().get("h")); - // not processex - assertNull(getopt.getOptValues().get("s")); - } - - @Test - public void testCommandWithSeparateOptions() { - setParams("-e -v install -h"); - - getopt.process(); - - String cmd = getopt.getCommand(); - Map opts = getopt.getOptValues(); - - assertNotNull(opts.get("e")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("h")); - assertEquals("install", cmd); - } - - @Test - public void testGlobalOptionAfterCommand() { - setParams("-e install -v -h"); - - getopt.process(); - - String cmd = getopt.getCommand(); - Map opts = getopt.getOptValues(); - - assertNotNull(opts.get("e")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("h")); - assertEquals("install", cmd); - } - - @Test - public void testPositonalParamsMixedWithOptions() { - setParams("-e -v install param1 -f param2 -r param3"); - - getopt.process(); - - Map opts = getopt.getOptValues(); - assertNotNull(opts.get("e")); - assertNotNull(opts.get("f")); - assertNotNull(opts.get("r")); - assertNull(opts.get("h")); - - assertEquals(Arrays.asList("param1", "param2", "param3"), getopt.getPositionalParameters()); - } - - @Test - public void testParametrizedOption() { - setParams("-C catalog -v install -h"); - getopt.process(); - - String cmd = getopt.getCommand(); - Map opts = getopt.getOptValues(); - - assertNotNull(opts.get("C")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("h")); - assertEquals("install", cmd); - assertEquals("catalog", opts.get("C")); - } - - @Test - public void testInterleavedParametrizedOptions() { - setParams("-e install param1 -C catalog param2 -r param3"); - getopt.process(); - - Map opts = getopt.getOptValues(); - assertNotNull(opts.get("e")); - assertNotNull(opts.get("C")); - assertNotNull(opts.get("r")); - assertEquals("catalog", opts.get("C")); - - assertEquals(Arrays.asList("param1", "param2", "param3"), getopt.getPositionalParameters()); - } - - @Test - public void testMaskedOutOption() { - setParams("-u list param1"); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnsupportedOption"); - getopt.process(); - } - - @Test - public void testMaskedOutOption2() { - setParams("list -u param1"); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnsupportedOption"); - getopt.process(); - } - - @Test - public void testMergedOptions() { - setParams("list param1 -vel param2"); - getopt.process(); - - Map opts = getopt.getOptValues(); - assertNotNull(opts.get("e")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("l")); - assertEquals(Arrays.asList("param1", "param2"), getopt.getPositionalParameters()); - } - - @Test - public void testOptionWithImmediateParameter() { - setParams("list param1 -veCcatalog param2"); - getopt.process(); - - Map opts = getopt.getOptValues(); - assertNotNull(opts.get("e")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("C")); - assertEquals("catalog", opts.get("C")); - assertEquals(Arrays.asList("param1", "param2"), getopt.getPositionalParameters()); - } - - @Test - public void testOptionsTerminated() { - setParams("-e install param1 -C catalog -- param2 -r param3"); - getopt.process(); - - Map opts = getopt.getOptValues(); - assertNotNull(opts.get("e")); - assertNotNull(opts.get("C")); - assertNull(opts.get("r")); - assertEquals("catalog", opts.get("C")); - - assertEquals(Arrays.asList("param1", "param2", "-r", "param3"), getopt.getPositionalParameters()); - } - - @Test - public void testAmbiguousCommand() { - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_AmbiguousCommand"); - setParams("in"); - getopt.process(); - } - - @Test - public void testEmptyCommand() { - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_MissingCommand"); - getopt.setParameters(new LinkedList<>(Arrays.asList(""))); - getopt.process(); - } - - @Test - public void testEmptyParameter() { - getopt.setParameters(new LinkedList<>(Arrays.asList("install", ""))); - getopt.process(); - assertEquals(Arrays.asList(""), getopt.getPositionalParameters()); - } - - @Test - public void testDoubleDashOption() { - setParams("--e --v install --x param1"); - - getopt.process(); - - String cmd = getopt.getCommand(); - Map opts = getopt.getOptValues(); - - assertNotNull(opts.get("e")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("x")); - assertEquals("install", cmd); - assertEquals(Arrays.asList("param1"), getopt.getPositionalParameters()); - } - - @Test - public void testDoubleDashParamOption() { - setParams("--e --v install --C catalog --x param1"); - - getopt.process(); - - String cmd = getopt.getCommand(); - Map opts = getopt.getOptValues(); - - assertNotNull(opts.get("e")); - assertNotNull(opts.get("v")); - assertNotNull(opts.get("x")); - assertNotNull(opts.get("C")); - assertEquals("catalog", opts.get("C")); - - assertEquals("install", cmd); - assertEquals(Arrays.asList("param1"), getopt.getPositionalParameters()); - } - - @Test - public void testLongOption() { - setParams("--help"); - getopt.process(); - - Map opts = getopt.getOptValues(); - assertNotNull(opts.get("h")); - - // should not be interpreted as a series of single options: - assertNull(opts.get("e")); - assertNull(opts.get("l")); - assertNull(opts.get("p")); - } - - @Test - public void testLongOptionAppendedParameter() { - setParams("--catalogbubu"); - - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_UnsupportedGlobalOption"); - getopt.process(); - } - - @Test - public void testLongOptionWithParameterBeforeCommand() { - setParams("--custom-catalog bubu install"); - - getopt.process(); - - Map opts = getopt.getOptValues(); - assertEquals("bubu", opts.get("C")); - } - - @Test - public void testLongOptionWithParameterAfterCommand() { - setParams("install --custom-catalog bubu "); - - getopt.process(); - Map opts = getopt.getOptValues(); - assertEquals("bubu", opts.get("C")); - } - - @Test - public void testComputeAbbreviations() { - setParams("install --user bubu"); - Map abbrevs = getopt.computeAbbreviations(Arrays.asList("list", "list-files", "file-list", "force", "replace", "rewrite", "verify", "signature")); - - assertEquals(null, abbrevs.get("list")); - assertEquals("list-files", abbrevs.get("list-")); - assertEquals("list-files", abbrevs.get("list-file")); - - assertEquals("force", abbrevs.get("fo")); - - assertEquals(null, abbrevs.get("re")); - assertEquals("rewrite", abbrevs.get("rew")); - assertEquals("replace", abbrevs.get("rep")); - } - - @Test - public void testLongOptionAbbreviation() { - setParams("install --long-user bubu"); - - getopt.process(); - Map opts = getopt.getOptValues(); - assertEquals("bubu", opts.get("U")); - } - - @Test - public void testOptionAliasesNoParam() { - setParams("install -F bubu"); - getopt.process(); - Map opts = getopt.getOptValues(); - assertEquals("", opts.get("L")); - } - - @Test - public void testOptionAliasesParamsCommand() { - setParams("install -9 bubu"); - getopt.addCommandOption("install", "9", "=C"); - getopt.process(); - Map opts = getopt.getOptValues(); - assertEquals("bubu", opts.get("C")); - } - - @Test - public void testOptionAliasesParamsGlobal() { - setParams("install -8 bubu"); - getopt.process(); - Map opts = getopt.getOptValues(); - assertEquals("bubu", opts.get("C")); - } - - @Test - public void testIgnoreUnknownCommands() { - setParams("-v bubak 1"); - getopt.ignoreUnknownCommands(true); - getopt.process(); - Map opts = getopt.getOptValues(); - assertEquals(1, opts.size()); - assertNotNull(opts.get("v")); - - assertEquals(2, getopt.getPositionalParameters().size()); - assertEquals("bubak", getopt.getPositionalParameters().get(0)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SystemUtilsTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SystemUtilsTest.java deleted file mode 100644 index ef4e086f2400..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/SystemUtilsTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * - * @author sdedic - */ -public class SystemUtilsTest { - @Rule public ExpectedException exception = ExpectedException.none(); - - @Test - public void testDiscardEmptyComponents() throws Exception { - Path base = Paths.get("graalvm"); - Path resolved = SystemUtils.fromCommonRelative(base, "jre/lib//svm/macros/graalpython-launcher/native-image.properties"); // NOI18N - for (Path p : resolved) { - assertFalse(p.toString().isEmpty()); - } - assertEquals("jre/lib/svm/macros/graalpython-launcher/native-image.properties", SystemUtils.toCommonPath(resolved)); - } - - @Test - public void testDiscardEmptyDoesNotAddLevel() throws Exception { - Path base = Paths.get("graalvm"); - exception.expect(IllegalArgumentException.class); - SystemUtils.fromCommonRelative(base, "jre/lib//../../../error"); // NOI18N - } - - @Test - public void testNoURLParameters() throws Exception { - Map params = new HashMap<>(); - String base = SystemUtils.parseURLParameters("http://acme.org/bu?", params); - assertEquals("http://acme.org/bu", base); - assertEquals(0, params.size()); - } - - @Test - public void testURLParameterNoEqual() throws Exception { - Map params = new HashMap<>(); - String base = SystemUtils.parseURLParameters("http://acme.org/bu?a", params); - assertEquals("http://acme.org/bu", base); - assertEquals(1, params.size()); - assertEquals("", params.get("a")); - } - - @Test - public void testURLMoreParametersNoEqual() throws Exception { - Map params = new HashMap<>(); - String base = SystemUtils.parseURLParameters("http://acme.org/bu?a&b", params); - assertEquals("http://acme.org/bu", base); - assertEquals(2, params.size()); - assertEquals("", params.get("a")); - assertEquals("", params.get("b")); - } - - @Test - public void testURLParameterOnlyEqual() throws Exception { - Map params = new HashMap<>(); - String base = SystemUtils.parseURLParameters("http://acme.org/bu?a=", params); - assertEquals("http://acme.org/bu", base); - assertEquals(1, params.size()); - assertEquals("", params.get("a")); - } - - @Test - public void testURLMoreParametersOnlyEqual() throws Exception { - Map params = new HashMap<>(); - String base = SystemUtils.parseURLParameters("http://acme.org/bu?a=&b=", params); - assertEquals("http://acme.org/bu", base); - assertEquals(2, params.size()); - assertEquals("", params.get("a")); - assertEquals("", params.get("b")); - } - - @Test - public void testBuildUrlStringWithParameters() throws Exception { - Map> params = new HashMap<>(); - String baseUrl = "http://acme.org/bu"; - String url = SystemUtils.buildUrlStringWithParameters(baseUrl, params); - assertEquals(baseUrl, url); - - List param1 = new ArrayList<>(); - params.put("a", param1); - url = SystemUtils.buildUrlStringWithParameters(baseUrl, params); - assertEquals(baseUrl, url); - - param1.add("b"); - url = SystemUtils.buildUrlStringWithParameters(baseUrl, params); - assertEquals(baseUrl + "?a=b", url); - - param1.add("c"); - url = SystemUtils.buildUrlStringWithParameters(baseUrl, params); - assertEquals(baseUrl + "?a=b&a=c", url); - - List param2 = new ArrayList<>(); - param2.add("e"); - params.put("d", param2); - url = SystemUtils.buildUrlStringWithParameters(baseUrl, params); - assertEquals(baseUrl + "?a=b&a=c&d=e", url); - - params.clear(); - param1.clear(); - param1.add("\""); - params.put("&", param1); - url = SystemUtils.buildUrlStringWithParameters(baseUrl, params); - assertEquals(baseUrl + "?%26=%22", url); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/TestBase.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/TestBase.java deleted file mode 100644 index 71108761f718..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/TestBase.java +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.text.MessageFormat; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import org.junit.After; - -import org.junit.AfterClass; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.rules.TemporaryFolder; -import org.junit.rules.TestName; - -/** - * Boilerplate for tests. - */ -public class TestBase implements Feedback { - private static final ResourceBundle NO_BUNDLE = new ResourceBundle() { - @Override - protected Object handleGetObject(String key) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Enumeration getKeys() { - throw new UnsupportedOperationException("Not supported yet."); - } - }; - protected ResourceBundle defaultBundle = ResourceBundle.getBundle("org.graalvm.component.installer.Bundle"); // NOI18N - private Feedback feedbackDelegate; - protected boolean verbose; - - @ClassRule public static TemporaryFolder expandedFolder = new ClassTempFolder(); - @Rule public TemporaryFolder testFolder = new TemporaryFolder(); - @Rule public TestName testName = new TestName(); - - public TestBase() { - } - - @Override - public boolean isSilent() { - return feedbackDelegate == null ? false : feedbackDelegate.isSilent(); - } - - @Override - public boolean setSilent(boolean silent) { - return feedbackDelegate == null ? false : feedbackDelegate.setSilent(silent); - } - - @Override - public void addLocalResponseHeadersCache(URL location, Map> local) { - - } - - @Override - public Map> getLocalResponseHeadersCache(URL location) { - return null; - } - - static class ClassTempFolder extends TemporaryFolder { - ThreadLocal root = new ThreadLocal<>(); - - @Override - public void delete() { - File folder = root.get(); - if (folder != null) { - recursiveDelete(folder); - } - root.set(null); - } - - private void recursiveDelete(File file) { - File[] files = file.listFiles(); - if (files != null) { - for (File each : files) { - recursiveDelete(each); - } - } - file.delete(); - } - - @Override - public File getRoot() { - return root.get(); - } - - @Override - public void create() throws IOException { - File createdFolder = File.createTempFile("junit", "", null); - createdFolder.delete(); - createdFolder.mkdir(); - root.set(createdFolder); - } - - } - - protected static Path expandedJarPath = null; - - protected void delegateFeedback(Feedback delegate) { - this.feedbackDelegate = delegate; - } - - @AfterClass - public static void cleanupExpandedPath() { - expandedJarPath = null; - } - - public void expandJar() throws IOException { - if (expandedJarPath != null) { - return; - } - URL location = getClass().getProtectionDomain().getCodeSource().getLocation(); - File f; - try { - f = new File(location.toURI()); - } catch (URISyntaxException ex) { - fail(ex.getMessage()); - return; // keep compiler happy - } - if (f.isDirectory()) { - // ok, we can access files directly - return; - } - expandedJarPath = expandedFolder.newFolder("expanded-data").toPath(); - JarFile jf = new JarFile(f); - for (JarEntry en : Collections.list(jf.entries())) { - Path target = expandedJarPath.resolve(SystemUtils.fromCommonString(en.getName())); - if (en.isDirectory()) { - Files.createDirectories(target); - } else { - Files.createDirectories(target.getParent()); - try (InputStream is = jf.getInputStream(en)) { - Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING); - } - } - } - } - - protected Path dataFile(String relative) throws IOException { - expandJar(); - URL u = getClass().getClassLoader().getResource(getClass().getName().replace('.', '/') + ".class"); - Path basePath; - if (expandedJarPath != null) { - String n = getClass().getName(); - n = n.substring(0, n.lastIndexOf('.')).replace('.', '/'); - basePath = expandedJarPath.resolve(SystemUtils.fromCommonString(n)); - } else { - try { - basePath = Paths.get(u.toURI()).getParent(); - } catch (URISyntaxException ex) { - fail("URI error"); - return null; - } - } - return basePath.resolve(SystemUtils.fromCommonString(relative)); - } - - protected InputStream dataStream(String relative) { - String n = getClass().getName(); - n = n.substring(0, n.lastIndexOf('.')).replace('.', '/'); - return getClass().getClassLoader().getResourceAsStream(n + "/" + relative); - } - - protected void copyDir(String subdir, Path to) throws IOException { - Path subdirPath = dataFile(subdir); - Files.walkFileTree(subdirPath, new CopyDir(subdirPath, to)); - } - - public class CopyDir extends SimpleFileVisitor { - private Path sourceDir; - private Path targetDir; - - public CopyDir(Path sourceDir, Path targetDir) { - this.sourceDir = sourceDir; - this.targetDir = targetDir; - } - - @Override - public FileVisitResult visitFile(Path file, - BasicFileAttributes attributes) throws IOException { - Path targetFile = targetDir.resolve(sourceDir.relativize(file)); - Files.copy(file, targetFile); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, - BasicFileAttributes attributes) throws IOException { - Path newDir = targetDir.resolve(sourceDir.relativize(dir)); - Files.createDirectories(newDir); - return FileVisitResult.CONTINUE; - } - } - - public void message(ResourceBundle bundle, String bundleKey, Object... params) { - if (bundle != null) { - MessageFormat.format(bundle.getString(bundleKey), params); - } - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(bundle == null ? NO_BUNDLE : bundle); - } - if (feedbackDelegate != null) { - feedbackDelegate.message(bundleKey, params); - } - } - - public void output(ResourceBundle bundle, String bundleKey, Object... params) { - if (bundle != null) { - MessageFormat.format(bundle.getString(bundleKey), params); - } - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(bundle == null ? NO_BUNDLE : bundle); - } - if (feedbackDelegate != null) { - feedbackDelegate.output(bundleKey, params); - } - } - - @Override - public void outputPart(String bundleKey, Object... params) { - output(defaultBundle, bundleKey, params); - } - - @Override - public boolean verbatimPart(String msg, boolean error, boolean beVerbose) { - return verbatimPart(msg, beVerbose); - } - - @Override - public boolean verbatimPart(String msg, boolean beVerbose) { - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(NO_BUNDLE); - } - try { - if (feedbackDelegate != null) { - return feedbackDelegate.verbatimPart(msg, beVerbose); - } - } finally { - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(null); - } - } - return verbose; - } - - public void verbosePart(ResourceBundle bundle, String bundleKey, Object... params) { - if (bundle != null && bundleKey != null) { - MessageFormat.format(bundle.getString(bundleKey), params); - } - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(bundle == null ? NO_BUNDLE : bundle); - } - if (feedbackDelegate != null) { - feedbackDelegate.verbosePart(bundleKey, params); - } - } - - public void verboseOutput(ResourceBundle bundle, String bundleKey, Object... params) { - if (bundle != null && bundleKey != null) { - MessageFormat.format(bundle.getString(bundleKey), params); - } - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(bundle == null ? NO_BUNDLE : bundle); - } - if (feedbackDelegate != null) { - feedbackDelegate.verboseOutput(bundleKey, params); - } - } - - public void error(ResourceBundle bundle, String key, Throwable t, Object... params) { - if (bundle != null) { - MessageFormat.format(bundle.getString(key), params); - } - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(bundle == null ? NO_BUNDLE : bundle); - } - if (feedbackDelegate != null) { - feedbackDelegate.error(key, t, params); - } - } - - public String l10n(ResourceBundle bundle, String key, Object... params) { - if (bundle != null) { - MessageFormat.format(bundle.getString(key), params); - } - if (feedbackDelegate != null) { - String s; - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(bundle); - } - s = feedbackDelegate.l10n(key, params); - if (s != null) { - return s; - } - } - if (key.endsWith("@") && bundle != null) { - return MessageFormat.format(bundle.getString(key), params); - } else { - return key; - } - } - - public String reallyl10n(ResourceBundle bundle, String key, Object... params) { - ResourceBundle b = bundle != null ? bundle : defaultBundle; - return MessageFormat.format(b.getString(key), params); - } - - @Override - public boolean verbatimOut(String msg, boolean verboseOutput) { - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(NO_BUNDLE); - } - try { - if (verboseOutput) { - verboseOutput((ResourceBundle) null, msg); - } else { - if (feedbackDelegate != null) { - feedbackDelegate.verbatimOut(msg, verboseOutput); - } - output((ResourceBundle) null, msg); - } - } finally { - if (feedbackDelegate instanceof FeedbackAdapter) { - ((FeedbackAdapter) feedbackDelegate).setBundle(null); - } - } - return verboseOutput; - } - - public RuntimeException failure(ResourceBundle bundle, String key, Throwable t, Object... params) { - MessageFormat.format(bundle.getString(key), params); - throw new FailedOperationException(key, t); - } - - @Override - public void message(String bundleKey, Object... params) { - message(defaultBundle, bundleKey, params); - } - - @Override - public void output(String bundleKey, Object... params) { - output(defaultBundle, bundleKey, params); - } - - @Override - public boolean backspace(int chars, boolean beVerbose) { - if (beVerbose && !verbose) { - return false; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < chars; i++) { - sb.append('\b'); - } - if (beVerbose) { - verbosePart((ResourceBundle) null, sb.toString()); - } else { - output((ResourceBundle) null, sb.toString()); - } - return verbose; - } - - @Override - public boolean verbosePart(String bundleKey, Object... params) { - verbosePart(defaultBundle, bundleKey, params); - return verbose; - } - - @Override - public boolean verboseOutput(String bundleKey, Object... params) { - verboseOutput(defaultBundle, bundleKey, params); - return verbose; - } - - @Override - public void error(String key, Throwable t, Object... params) { - error(defaultBundle, key, t, params); - } - - @Override - public String l10n(String key, Object... params) { - return l10n(defaultBundle, key, params); - } - - @Override - public RuntimeException failure(String key, Throwable t, Object... params) { - return failure(defaultBundle, key, t, params); - } - - @Override - public Feedback withBundle(Class clazz) { - return new WB(clazz); - } - - class WB implements Feedback { - ResourceBundle localBundle; - - @Override - public void message(String bundleKey, Object... params) { - TestBase.this.message(localBundle, bundleKey, params); - } - - @Override - public void output(String bundleKey, Object... params) { - TestBase.this.output(localBundle, bundleKey, params); - } - - @Override - public boolean verbosePart(String bundleKey, Object... params) { - TestBase.this.verbosePart(localBundle, bundleKey, params); - return verbose; - } - - @Override - public boolean verboseOutput(String bundleKey, Object... params) { - TestBase.this.verboseOutput(localBundle, bundleKey, params); - return verbose; - } - - @Override - public void error(String key, Throwable t, Object... params) { - TestBase.this.error(localBundle, key, t, params); - } - - @Override - public String l10n(String key, Object... params) { - return TestBase.this.l10n(localBundle, key, params); - } - - @Override - public RuntimeException failure(String key, Throwable t, Object... params) { - return TestBase.this.failure(localBundle, key, t, params); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - return TestBase.this.verbatimOut(msg, beVerbose); - } - - WB(Class clazz) { - String s = clazz.getName(); - s = s.substring(0, s.lastIndexOf('.')); - this.localBundle = ResourceBundle.getBundle(s + ".Bundle"); // NOI18N - } - - @Override - public Feedback withBundle(Class clazz) { - return new WB(clazz); - } - - @Override - public void outputPart(String bundleKey, Object... params) { - TestBase.this.output(localBundle, bundleKey, params); - } - - @Override - public boolean verbatimPart(String msg, boolean error, boolean beVerbose) { - return TestBase.this.verbatimPart(msg, error, beVerbose); - } - - @Override - public boolean verbatimPart(String msg, boolean beVerbose) { - return TestBase.this.verbatimPart(msg, beVerbose); - } - - @Override - public boolean backspace(int chars, boolean beVerbose) { - return TestBase.this.backspace(chars, beVerbose); - } - - @Override - public String acceptLine(boolean autoYes) { - return TestBase.this.acceptLine(autoYes); - } - - @Override - public char[] acceptPassword() { - return TestBase.this.acceptPassword(); - } - - @Override - public void addLocalFileCache(URL location, Path local) { - TestBase.this.addLocalFileCache(location, local); - } - - @Override - public Path getLocalCache(URL location) { - return TestBase.this.getLocalCache(location); - } - - @Override - public boolean isNonInteractive() { - return TestBase.this.isNonInteractive(); - } - - @Override - public boolean isSilent() { - return TestBase.this.isSilent(); - } - - @Override - public boolean setSilent(boolean silent) { - return TestBase.this.setSilent(silent); - } - - @Override - public void addLocalResponseHeadersCache(URL location, Map> local) { - TestBase.this.addLocalResponseHeadersCache(location, local); - } - - @Override - public Map> getLocalResponseHeadersCache(URL location) { - return TestBase.this.getLocalResponseHeadersCache(location); - } - } - - public class FeedbackAdapter implements Feedback { - private ResourceBundle currentBundle; - private boolean silent; - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - return verbose; - } - - @Override - public void message(String bundleKey, Object... params) { - } - - @Override - public void output(String bundleKey, Object... params) { - } - - @Override - public boolean verbosePart(String bundleKey, Object... params) { - return verbose; - } - - @Override - public boolean verboseOutput(String bundleKey, Object... params) { - return verbose; - } - - @Override - public void error(String key, Throwable t, Object... params) { - } - - @Override - public String l10n(String key, Object... params) { - return null; - } - - @Override - public RuntimeException failure(String key, Throwable t, Object... params) { - return null; - } - - @Override - public Feedback withBundle(Class clazz) { - return this; - } - - @Override - public void outputPart(String bundleKey, Object... params) { - } - - @Override - public boolean verbatimPart(String msg, boolean error, boolean beVerbose) { - return verbose; - } - - @Override - public boolean verbatimPart(String msg, boolean beVerbose) { - return verbose; - } - - @Override - public boolean backspace(int chars, boolean beVerbose) { - return verbose; - } - - protected String reallyl10n(String k, Object... params) { - return TestBase.this.reallyl10n(getBundle(), k, params); - } - - protected ResourceBundle getBundle() { - if (currentBundle == NO_BUNDLE) { - return null; - } - if (currentBundle != null) { - return currentBundle; - } - return defaultBundle; - } - - void setBundle(ResourceBundle bundle) { - this.currentBundle = bundle; - } - - @Override - public String acceptLine(boolean autoYes) { - return TestBase.this.doAcceptLine(autoYes); - } - - @Override - public char[] acceptPassword() { - return TestBase.this.doAcceptPassword(); - } - - @Override - public void addLocalFileCache(URL location, Path local) { - TestBase.this.addLocalFileCache(location, local); - } - - @Override - public Path getLocalCache(URL location) { - return TestBase.this.getLocalCache(location); - } - - @Override - public boolean isNonInteractive() { - return TestBase.this.isNonInteractive(); - } - - @Override - public boolean isSilent() { - return silent; - } - - @Override - public boolean setSilent(boolean silent) { - boolean wasSilent = this.silent; - this.silent = silent; - return wasSilent; - } - - @Override - public void addLocalResponseHeadersCache(URL location, Map> local) { - TestBase.this.addLocalResponseHeadersCache(location, local); - } - - @Override - public Map> getLocalResponseHeadersCache(URL location) { - return TestBase.this.getLocalResponseHeadersCache(location); - } - } - - @Override - public boolean isNonInteractive() { - return false; - } - - public static boolean isWindows() { - return SystemUtils.isWindows(); - } - - protected StringBuilder userInput = new StringBuilder(); - protected String password; - protected boolean autoYesEnabled; - - @Override - public String acceptLine(boolean autoYes) { - if (feedbackDelegate != null) { - return feedbackDelegate.acceptLine(autoYes); - } - return doAcceptLine(autoYes); - } - - String doAcceptLine(boolean autoYes) { - if (autoYes && autoYesEnabled) { - return AUTO_YES; - } - int nl = userInput.indexOf("\n"); - if (nl < 0) { - nl = userInput.length(); - } - String r = userInput.substring(0, nl); - userInput.delete(0, nl + 1); // including the newline - return r; - } - - @Override - public char[] acceptPassword() { - if (feedbackDelegate != null) { - return feedbackDelegate.acceptPassword(); - } - return doAcceptPassword(); - } - - public char[] doAcceptPassword() { - return password == null ? null : password.toCharArray(); - } - - @Override - public void addLocalFileCache(URL location, Path local) { - - } - - @Override - public Path getLocalCache(URL location) { - return null; - } - - @After - public void disableLicenseAfterTest() { - SystemUtils.licenseTracking = false; - } - - public static void enableLicensesForTesting() { - SystemUtils.licenseTracking = true; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/VersionTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/VersionTest.java deleted file mode 100644 index 7267fc4081b1..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/VersionTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * - * @author sdedic - */ -public class VersionTest { - @Rule public ExpectedException exception = ExpectedException.none(); - - @Test - public void testNoVersionInfimum() throws Exception { - Version otherNullVersion = Version.fromString(Version.NO_VERSION.toString()); - - assertTrue(otherNullVersion.compareTo(Version.NO_VERSION) > 0); - assertTrue(Version.NO_VERSION.compareTo(otherNullVersion) < 0); - - assertFalse(otherNullVersion.equals(Version.NO_VERSION)); - assertFalse(Version.NO_VERSION.equals(otherNullVersion)); - } - - @Test - public void testNoVersionEqualToSelf() throws Exception { - assertTrue(Version.NO_VERSION.compareTo(Version.NO_VERSION) == 0); - assertTrue(Version.NO_VERSION.equals(Version.NO_VERSION)); - } - - @Test - public void testNormalizeTo4Numbers() throws Exception { - assertEquals("1.0.0.0-0.r", Version.fromString("1.0-r").toString()); - assertEquals("1.0.0.0-0.r", Version.fromString("1.0.0-r").toString()); - assertEquals("1.0.0.0-0.r", Version.fromString("1.0.0.0-r").toString()); - } - - @Test - public void testFailOnTooManyVersions() throws Exception { - exception.expect(IllegalArgumentException.class); - assertEquals("1.0.0.0.0-r", Version.fromString("1.0.0.0.0-r").toString()); - } - - @Test - public void testFailOnTooFewVersions() throws Exception { - exception.expect(IllegalArgumentException.class); - assertEquals("1-r", Version.fromString("1.0.0.0.0-r").toString()); - } - - private static void assertOlder(String older, String newer) { - assertTrue("Versions didn't compare " + older + " < " + newer, - Version.fromString(older).compareTo(Version.fromString(newer)) < 0); - assertFalse(older.equals(newer)); - } - - @Test - public void testVersionOrder() throws Exception { - String[] versionSequence = { - "1.0", - "1.0.1", - "1.1.0", - "1.1.0-0.dev.1", - "1.1.0-0.dev.2", - "1.1.0-0.dev8", - "1.1.0-0.dev.10", - "1.1.0-0.dev13", - "1.1.0-1.beta1", - "1.1.0-1.beta-3", - "1.1.0-1.beta.9", - "1.1.0-1.beta.10", - "1.1.0-1.beta.13", - "1.1.0-1.beta15", - "1.1.0-2", - "1.1.0.2-0.rc.1", - "1.1.0.2-1", - "1.1.0.3", - }; - - for (int i = 0; i < versionSequence.length; i++) { - for (int j = i + 1; j < versionSequence.length; j++) { - assertOlder(versionSequence[i], versionSequence[j]); - } - } - } - - @Test - public void testComponentizeVersion() { - assertEquals("1.0.0.0-0.rc.1", Version.fromString("1.0.0-rc1").toString()); - } - - @Test - public void testDisplayReleaseVersions() { - assertEquals("1.0.0", Version.fromString("1.0.0.0").displayString()); - assertEquals("1.0.0", Version.fromString("1.0.0.0-1").displayString()); - } - - @Test - public void testDisplayPreReleases() { - assertEquals("1.0.0-rc1", Version.fromString("1.0.0.0-1.rc.1").displayString()); - assertEquals("1.0.0-rc9", Version.fromString("1.0.0.0-1.rc.9").displayString()); - } - - @Test - public void testDisplayPreReleaseBuilds() { - assertEquals("1.0.0-beta1.1", Version.fromString("1.0.0.0-1.beta.1.1").displayString()); - assertEquals("1.0.0-beta1.b2", Version.fromString("1.0.0.0-1.beta.1.b.2").displayString()); - } - - @Test - public void testDisplayWildardVersions() { - assertEquals("1.0.0-beta1.1", Version.fromString("1.0.0.0-*.beta.1.1").displayString()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/AvailableTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/AvailableTest.java deleted file mode 100644 index bd588d00741d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/AvailableTest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.util.List; -import java.util.Locale; -import java.util.Properties; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENTS; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import org.graalvm.component.installer.remote.GraalEditionList; -import org.graalvm.component.installer.MemoryFeedback; -import org.graalvm.component.installer.MemoryFeedback.Memory; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONObject; -import org.graalvm.shadowed.org.json.JSONTokener; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class AvailableTest extends CommandTestBase { - - private static final String GRAALVM_CE_202_CATALOG = "test://www.graalvm.org/graalvm-20.2-with-updates.properties"; - private static final String GRAALVM_EE_202_CATALOG = "test://www.graalvm.org/graalvmee-20.2-with-updates.properties"; - - private static final String GVM_VERSION = "20.2.0"; - private static final String STABILITY = "ComponentStabilityLevel_undefined"; - - @Rule public final ProxyResource proxyResource = new ProxyResource(); - - private void loadReleaseFile(String name) throws IOException { - try (InputStream stm = getClass().getResourceAsStream("data/" + name)) { - Properties props = new Properties(); - props.load(stm); - props.stringPropertyNames().forEach((s) -> { - String val = props.getProperty(s); - if (val.startsWith("\"") && val.endsWith("\"")) { - val = val.substring(1, val.length() - 1); - } - this.storage.graalInfo.put(s.toLowerCase(Locale.ENGLISH), val); - }); - } - } - - private GraalEditionList editionList; - private AvailableCommand cmd; - - void setupReleaseAndCatalog() throws Exception { - loadReleaseFile("release21ceWithEE.properties"); - - Path f = dataFile("data/graalvm-20.2-with-updates.properties"); - Handler.bind(GRAALVM_CE_202_CATALOG, f.toUri().toURL()); - - Path f2 = dataFile("data/graalvmee-20.2-with-updates.properties"); - Handler.bind(GRAALVM_EE_202_CATALOG, f2.toUri().toURL()); - } - - private void initRemoteStorage() { - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - this.registry = list.createComponentCatalog(this); - this.editionList = list; - } - - void setupGraalVM202() throws Exception { - setupReleaseAndCatalog(); - initRemoteStorage(); - - cmd = new AvailableCommand(); - cmd.init(this, this.withBundle(AvailableCommand.class)); - cmd.execute(); - } - - @Override - public CatalogFactory getCatalogFactory() { - return editionList; - } - - /** - * By default, gu avail should list just its own release's component and NO core package so - * users are not confused. - * - * @throws Exception - */ - @Test - public void testDefaultListWithoutCorePackage() throws Exception { - setupGraalVM202(); - List infos = cmd.getComponents(); - // no core is listed: - assertFalse(infos.stream().filter(i -> CommonConstants.GRAALVM_CORE_PREFIX.equals(i.getId())).findAny().isPresent()); - } - - /** - * Checks that by default, only compatible components are listed, EXCEPT the core, which is - * listed in its newest version, if enabled by switch. - * - * @throws Exception - */ - @Test - public void testDefaultListOnlyCompatibleVersions() throws Exception { - setupGraalVM202(); - List infos = cmd.getComponents(); - // no version other than 20.2.0 is listed: - assertFalse(infos.stream().filter(i -> !i.getVersion().displayString().contains(GVM_VERSION)).findAny().isPresent()); - } - - /** - * Checks that by default, only compatible components are listed, EXCEPT the core, which is - * listed in its newest version, if enabled by switch. - * - * @throws Exception - */ - @Test - public void testListCompatibleVersionsPlusCore() throws Exception { - options.put(Commands.OPTION_SHOW_CORE, ""); - setupGraalVM202(); - List infos = cmd.getComponents(); - // no version other than 20.2.0 is listed: - assertFalse(infos.stream().filter(i -> !i.getVersion().displayString().contains(GVM_VERSION)).findAny().isPresent()); - // the core IS listed! - assertTrue(infos.stream().filter(i -> CommonConstants.GRAALVM_CORE_PREFIX.equals(i.getId())).findAny().isPresent()); - } - - /** - * Checks that updates are listed with a switch. Implies --show-core. - */ - @Test - public void testListUpdates() throws Exception { - options.put(Commands.OPTION_SHOW_UPDATES, ""); - setupGraalVM202(); - List infos = cmd.getComponents(); - // no version other than 20.2.0 is listed: - assertTrue(infos.stream().filter(i -> !i.getVersion().displayString().contains(GVM_VERSION)).findAny().isPresent()); - // the core IS listed! - assertTrue(infos.stream().filter(i -> CommonConstants.GRAALVM_CORE_PREFIX.equals(i.getId())).findAny().isPresent()); - } - - private static ComponentInfo findComponent(List list, String id) { - return list.stream().filter(i -> id.equals(i.getId())).findAny().orElse(null); - } - - /** - * Checks that edition component(s) are listed. Implies --show-core. Note the test data for 20.2 - * does not list R and Python components - * - * @throws Exception - */ - @Test - public void testListEECurrentVersion() throws Exception { - options.put(Commands.OPTION_USE_EDITION, "ee"); - setupGraalVM202(); - List infos = cmd.getComponents(); - - assertNull(findComponent(infos, "org.graalvm.python")); - assertNull(findComponent(infos, "org.graalvm.r")); - - assertNotNull(findComponent(infos, "org.graalvm.ruby")); - assertNotNull(findComponent(infos, "org.graalvm")); - } - - /** - * Checks that edition component(s) are listed. Implies --show-core. Now updates for 20.3.0 - * should be visible. - * - * @throws Exception - */ - @Test - public void testListEEUpdates() throws Exception { - options.put(Commands.OPTION_SHOW_UPDATES, ""); - options.put(Commands.OPTION_USE_EDITION, "ee"); - setupGraalVM202(); - List infos = cmd.getComponents(); - - assertNotNull(findComponent(infos, "org.graalvm.python")); - assertNotNull(findComponent(infos, "org.graalvm.R")); - - assertNotNull(findComponent(infos, "org.graalvm.ruby")); - assertNotNull(findComponent(infos, "org.graalvm")); - } - - /** - * Disables the default version filter. - */ - @Test - public void testListAll() throws Exception { - options.put(Commands.OPTION_ALL, ""); - setupGraalVM202(); - List infos = cmd.getComponents(); - - assertTrue(infos.size() > 8); - } - - @Test - public void testJSONOutput() throws Exception { - options.put(Commands.OPTION_JSON_OUTPUT, ""); - MemoryFeedback mf = new MemoryFeedback(); - this.delegateFeedback(mf); - setupGraalVM202(); - for (Memory mem : mf) { - if (!mem.silent) { - JSONObject jo = new JSONObject(new JSONTokener(mem.key)); - JSONArray comps = jo.getJSONArray(JSON_KEY_COMPONENTS); - assertEquals(6, comps.length()); - for (int i = 0; i < comps.length(); ++i) { - JSONObject comp = comps.getJSONObject(i); - assertEquals(comp.toString(2), GVM_VERSION, comp.getString(CommonConstants.JSON_KEY_COMPONENT_GRAALVM)); - assertEquals(comp.toString(2), GVM_VERSION, comp.getString(CommonConstants.JSON_KEY_COMPONENT_VERSION)); - assertEquals(comp.toString(2), STABILITY, comp.getString(CommonConstants.JSON_KEY_COMPONENT_STABILITY)); - assertTrue(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_ORIGIN) - .contains(comp.getString(CommonConstants.JSON_KEY_COMPONENT_ID).toLowerCase(Locale.ENGLISH) + "-installable-")); - assertTrue(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_NAME) != null); - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/BlockedFileOps.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/BlockedFileOps.java deleted file mode 100644 index 592cc95a306e..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/BlockedFileOps.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.FileSystemException; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermission; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.Callable; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.os.DefaultFileOperations; -import org.graalvm.component.installer.os.WindowsFileOperations; - -/** - * - * @author sdedic - */ -class BlockedFileOps extends WindowsFileOperations { - - class DefDelegate extends DefaultFileOperations { - - @Override - public Path handleUnmodifiableFile(IOException ex, Path p, InputStream content) throws IOException { - return super.handleUnmodifiableFile(ex, p, content); - } - - @Override - public void handleUndeletableFile(IOException ex, Path p) throws IOException { - super.handleUndeletableFile(ex, p); - } - - @Override - public boolean doWithPermissions(Path p, Callable action) throws IOException { - return super.doWithPermissions(p, action); - } - } - - private DefDelegate defSupport; - Set blockedPaths = new HashSet<>(); - Path delayDeletes; - Path copiedFiles; - - @Override - public void init(Feedback feedback) { - super.init(feedback); - defSupport = new DefDelegate(); - defSupport.init(feedback); - } - - @Override - protected void performInstall(Path target, InputStream contents) throws IOException { - if (blockedPaths.contains(target)) { - throw new FileSystemException(""); - } - super.performInstall(target, contents); - } - - @Override - protected void performDelete(Path target) throws IOException { - if (blockedPaths.contains(target)) { - throw new FileSystemException(""); - } - super.performDelete(target); - } - - @Override - public void setPermissions(Path target, Set perms) throws IOException { - if (SystemUtils.isWindows()) { - super.setPermissions(target, perms); - } else { - defSupport.setPermissions(target, perms); - } - } - - @Override - protected boolean doWithPermissions(Path p, Callable action) throws IOException { - if (SystemUtils.isWindows()) { - return super.doWithPermissions(p, action); - } else { - // make it OS-dependent way - return defSupport.doWithPermissions(p, action); - } - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/CatalogInstallTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/CatalogInstallTest.java deleted file mode 100644 index 0ed11b399adc..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/CatalogInstallTest.java +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.FileIterable; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.GraalEdition; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; - -/** - * - * @author sdedic - */ -public class CatalogInstallTest extends CommandTestBase { - private static final String TEST_CATALOG_URL = "test://release/catalog.properties"; - - @Rule public TestName name = new TestName(); - @Rule public ExpectedException exception = ExpectedException.none(); - @Rule public ProxyResource proxyResource = new ProxyResource(); - - protected InstallCommand inst; - private RemoteCatalogDownloader downloader; - - private void setupVersion(String v) { - String version = v == null ? "0.33" : v; - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, version); - } - - private void setupCatalog(String rel) throws Exception { - String relSpec; - - if (rel == null) { - relSpec = "catalog-" + name.getMethodName() + ".properties"; - if (getClass().getResource(relSpec) == null) { - if (name.getMethodName().contains("Deps")) { - relSpec = "cataloginstallDeps.properties"; - } else { - relSpec = "catalogInstallTest.properties"; - } - } - } else { - relSpec = rel; - } - URL u = getClass().getResource(relSpec); - if (u == null) { - u = getClass().getResource("catalogInstallTest.properties"); - } - Handler.bind(TEST_CATALOG_URL, u); - - downloader = new RemoteCatalogDownloader(this, this, SystemUtils.toURL(TEST_CATALOG_URL)); - this.registry = new CatalogContents(this, downloader.getStorage(), getLocalRegistry()); - } - - private void setupCatalog2(String rel) throws IOException { - Path p = dataFile(rel); - URL u = p.toUri().toURL(); - downloader = new RemoteCatalogDownloader(this, this, u); - this.registry = new CatalogContents(this, downloader.getStorage(), getLocalRegistry()); - } - - /** - * Checks that mismatched catalog is rejected entirely. - * - * @throws Exception - */ - @Test - public void testRejectMismatchingCatalog() throws Exception { - setupVersion("1.0.0-rc1"); - - URL rubyURL = SystemUtils.toURL("test://release/graalvm-ruby.zip"); - Handler.bind(rubyURL.toString(), new URLConnection(rubyURL) { - @Override - public void connect() throws IOException { - throw new UnsupportedOperationException("Should not be touched"); - } - }); - - exception.expect(IncompatibleException.class); - exception.expectMessage("REMOTE_UnsupportedGraalVersion"); - - setupCatalog(null); - textParams.add("ruby"); - paramIterable = new CatalogIterable(this, this); - paramIterable.iterator().next(); - } - - /** - * Checks that mismatched version is rejected based on catalog metadata, and the component URL - * is not opened at all. - * - * Because of versioning support, the "ruby" will not be even identifier as available, as it - * requires an incompatible graalvm version. - */ - @Test - public void testRejectMetaDontDownloadPackage() throws Exception { - setupVersion("0.33-dev"); - - URL rubyURL = SystemUtils.toURL("test://release/graalvm-ruby.zip"); - Handler.bind(rubyURL.toString(), new URLConnection(rubyURL) { - @Override - public void connect() throws IOException { - throw new UnsupportedOperationException( - "Should not be touched"); - } - }); - - exception.expect(DependencyException.Mismatch.class); - exception.expectMessage("VERIFY_ObsoleteGraalVM"); - - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("ruby"); - InstallCommand cmd = new InstallCommand(); - cmd.init(this, - withBundle(InstallCommand.class)); - cmd.execute(); - } - - @Test - public void testCheckPostinstMessageLoaded() throws Exception { - setupVersion("0.33"); - URL x = getClass().getResource("postinst2.jar"); - URL rubyURL = SystemUtils.toURL("test://release/postinst2.jar"); - Handler.bind(rubyURL.toString(), x); - - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("ruby"); - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - - cmd.prepareInstallation(); - cmd.completeInstallers(); - - assertFalse(cmd.realInstallers.isEmpty()); - for (Installer i : cmd.realInstallers.values()) { - assertNotNull(i.getComponentInfo().getPostinstMessage()); - } - } - - @Test - public void testPostinstMessagePrinted() throws Exception { - setupVersion("0.33"); - URL x = getClass().getResource("postinst2.jar"); - URL rubyURL = SystemUtils.toURL("test://release/postinst2.jar"); - Handler.bind(rubyURL.toString(), x); - - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("ruby"); - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - - String[] formatted = new String[1]; - delegateFeedback(new FeedbackAdapter() { - @Override - public boolean verbatimOut(String aMsg, boolean beVerbose) { - if (aMsg.contains("Ruby openssl")) { // NOI18N - formatted[0] = aMsg; - } - return super.verbatimOut(aMsg, beVerbose); - } - }); - cmd.execute(); - - assertNotNull(formatted[0]); - } - - @Test - public void testInstallWithDepsSingleLevel() throws Exception { - setupVersion("19.3-dev"); - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("r"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - - List deps = cmd.getDependencies(); - assertEquals(1, deps.size()); - assertEquals("org.graalvm.llvm-toolchain", deps.get(0).createMetaLoader().getComponentInfo().getId()); - } - - @Test - public void testInstallWithIgnoredDeps() throws Exception { - setupVersion("19.3-dev"); - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("r"); - options.put(Commands.OPTION_NO_DEPENDENCIES, ""); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - - List deps = cmd.getDependencies(); - assertTrue(deps.isEmpty()); - } - - @Test - public void testInstallWithBrokenDeps() throws Exception { - setupVersion("19.3-dev"); - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("additional"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - exception.expect(FailedOperationException.class); - exception.expectMessage("INSTALL_UnresolvedDependencies"); - try { - cmd.executeStep(cmd::prepareInstallation, false); - } catch (FailedOperationException ex) { - Set u = cmd.getUnresolvedDependencies(); - assertFalse(u.isEmpty()); - assertEquals("org.graalvm.unknown", u.iterator().next()); - throw ex; - } - } - - @Test - public void testInstallWithBrokenIgnoredDeps() throws Exception { - setupVersion("19.3-dev"); - setupCatalog(null); - paramIterable = new CatalogIterable(this, this); - textParams.add("additional"); - options.put(Commands.OPTION_NO_DEPENDENCIES, ""); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - } - - /** - * Checks that a dependency that is already installed is not installed again. - */ - @Test - public void testInstallDepsWithDependecnyInstalled() throws Exception { - setupVersion("19.3-dev"); - setupCatalog(null); - testInstallDepsWithDependecnyInstalledCommon(); - } - - private void testInstallDepsWithDependecnyInstalledCommon() throws Exception { - ComponentInfo fakeInfo = new ComponentInfo("org.graalvm.llvm-toolchain", "Fake Toolchain", "19.3-dev"); - fakeInfo.setInfoPath(""); - storage.installed.add(fakeInfo); - - paramIterable = new CatalogIterable(this, this); - textParams.add("r"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - assertTrue(cmd.getDependencies().isEmpty()); - } - - /** - * Checks that if a dependency is specified also on the commandline, the component is actually - * installed just once. - */ - @Test - public void testInstallDepsOnCommandLine() throws Exception { - setupVersion("19.3-dev"); - setupCatalog2("cataloginstallDeps.properties"); - testInstallDepsOnCommandLineCommon(); - } - - private void testInstallDepsOnCommandLineCommon() throws Exception { - paramIterable = new CatalogIterable(this, this); - textParams.add("r"); - textParams.add("llvm-toolchain"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - cmd.executeStep(cmd::completeInstallers, false); - - List instSequence = cmd.getInstallers(); - assertEquals(2, instSequence.size()); - ComponentInfo ci = instSequence.get(0).getComponentInfo(); - assertEquals("org.graalvm.llvm-toolchain", ci.getId()); - ci = instSequence.get(1).getComponentInfo(); - assertEquals("org.graalvm.r", ci.getId()); - } - - /** - * Checks that if a dependency is specified also on the commandline, the component is actually - * installed just once. In this case, the catalog does NOT specify dependencies, they are - * discovered only when the component's archive is loaded. - */ - @Test - public void testInstallDepsOnCommandLine2() throws Exception { - setupVersion("19.3-dev"); - setupCatalog2("cataloginstallDeps2.properties"); - testInstallDepsOnCommandLineCommon(); - } - - /** - * Checks that dependencies precede the component that uses them. In this case ruby > - * native-image > llvm-toolchain, so they should be installed in the opposite order. - */ - @Test - public void testDepsBeforeUsage() throws Exception { - setupVersion("19.3-dev"); - setupCatalog2("cataloginstallDeps.properties"); - testDepsBeforeUsageCommon(); - } - - /** - * The same as {@link #testDepsBeforeUsage()} except that dependency info is incomplete in the - * catalog. - * - * @throws Exception - */ - @Test - public void testDepsBeforeUsage2() throws Exception { - setupVersion("19.3-dev"); - setupCatalog2("cataloginstallDeps2.properties"); - testDepsBeforeUsageCommon(); - } - - private void testDepsBeforeUsageCommon() throws Exception { - paramIterable = new CatalogIterable(this, this); - textParams.add("ruby"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - cmd.executeStep(cmd::completeInstallers, false); - - List instSequence = cmd.getInstallers(); - assertEquals(3, instSequence.size()); - ComponentInfo ci = instSequence.get(0).getComponentInfo(); - assertEquals("org.graalvm.llvm-toolchain", ci.getId()); - ci = instSequence.get(1).getComponentInfo(); - assertEquals("org.graalvm.native-image", ci.getId()); - ci = instSequence.get(2).getComponentInfo(); - assertEquals("org.graalvm.ruby", ci.getId()); - } - - /** - * Checks that two same components on the commandline are merged, including their dependencies. - */ - @Test - public void testTwoSameComponentsCommandLineDeps() throws Exception { - setupVersion("19.3-dev"); - setupCatalog2("cataloginstallDeps.properties"); - testTwoSameComponentsCommandLineDepsCommon(); - } - - /** - * Checks that two same components on the commandline are merged, including their dependencies. - */ - @Test - public void testTwoSameComponentsCommandLineDeps2() throws Exception { - setupVersion("19.3-dev"); - setupCatalog2("cataloginstallDeps2.properties"); - testTwoSameComponentsCommandLineDepsCommon(); - } - - private void testTwoSameComponentsCommandLineDepsCommon() throws Exception { - paramIterable = new CatalogIterable(this, this); - textParams.add("r"); - textParams.add("r"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - cmd.executeStep(cmd::completeInstallers, false); - - List instSequence = cmd.getInstallers(); - assertEquals(2, instSequence.size()); - ComponentInfo ci = instSequence.get(0).getComponentInfo(); - assertEquals("org.graalvm.llvm-toolchain", ci.getId()); - ci = instSequence.get(1).getComponentInfo(); - assertEquals("org.graalvm.r", ci.getId()); - } - - CatalogFactory catalogFactory = null; - - @Override - public CatalogFactory getCatalogFactory() { - if (catalogFactory == null) { - return super.getCatalogFactory(); - } else { - return catalogFactory; - } - } - - /** - * Checks that dependencies can be loaded from the same directory as the installed Component. - */ - @Test - public void testInstallDependencyFromSameDirectory() throws Exception { - Path ruby193Source = dataFile("../repo/19.3.0.0/r"); - Path llvm193Source = dataFile("../repo/19.3.0.0/llvm-toolchain"); - - // they should be next to eah other - assertEquals(ruby193Source.getParent(), llvm193Source.getParent()); - files.add(ruby193Source.toFile()); - setupVersion("19.3.0.0"); - // no external catalog - downloader = new RemoteCatalogDownloader(this, this, (URL) null); - downloader.addLocalChannelSource( - new SoftwareChannelSource(ruby193Source.getParent().toFile().toURI().toString())); - catalogFactory = new CatalogFactory() { - @Override - public ComponentCatalog createComponentCatalog(CommandInput input) { - return new CatalogContents(CatalogInstallTest.this, downloader.getStorage(), input.getLocalRegistry()); - } - - @Override - public List listEditions(ComponentRegistry targetGraalVM) { - return Collections.emptyList(); - } - }; - FileIterable fit = new FileIterable(this, this); - fit.setCatalogFactory(catalogFactory); - paramIterable = fit; - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - assertFalse(cmd.getDependencies().isEmpty()); - } - - /** - * Tests, that a correct java version flavour gets selected if the catalog contains two flavours - * of the component in the requested version. - */ - @Test - public void testInstallCorrectJavaVersion8() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_JAVA_VERSION, "8"); - setupVersion("1.0.0.0"); - setupCatalog("catalogMultiFlavours.properties"); - - paramIterable = new CatalogIterable(this, this); - textParams.add("ruby"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - List installers = cmd.getInstallers(); - assertEquals(1, installers.size()); - } - - @Test - public void testInstallCorrectJavaVersion11() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_JAVA_VERSION, "11"); - setupVersion("1.0.0.0"); - setupCatalog("catalogMultiFlavours.properties"); - - paramIterable = new CatalogIterable(this, this); - textParams.add("ruby"); - - InstallCommand cmd = new InstallCommand(); - cmd.init(this, withBundle(InstallCommand.class)); - cmd.executionInit(); - - cmd.executeStep(cmd::prepareInstallation, false); - List installers = cmd.getInstallers(); - assertEquals(1, installers.size()); - } - - /** - * Version 20.3.0 should not accept 20.3.1 (20.3.1.2, 20.3.1.3, ...) components. - * - * @throws Exception - */ - @Test - public void testRejectNewerInstallVersion() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "20.3.0"); - setupCatalog("data/catalog21patch.properties"); - - textParams.add("llvm-toolchain"); - - paramIterable = new CatalogIterable(this, this); - Iterator params = paramIterable.iterator(); - assertTrue(params.hasNext()); - ComponentParam toolchainParam = params.next(); - ComponentInfo toolchainInfo = toolchainParam.createMetaLoader().getComponentInfo(); - assertNotNull(toolchainInfo); - assertEquals("org.graalvm.llvm-toolchain", toolchainInfo.getId()); - assertEquals("Only release is compatible", "20.3.0", toolchainInfo.getVersion().displayString()); - } - - /** - * Checks that all installable versions are collected. - * - * @throws Exception - */ - @Test - public void testCollectAllVersions() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "20.3.0"); - setupCatalog("data/catalog21patch.properties"); - - Collection infos = registry.loadComponents("ruby", localRegistry.getGraalVersion().match(Version.Match.Type.INSTALLABLE), false); - assertEquals("3 version equal or greater", 3, infos.size()); - - infos = registry.loadComponents("ruby", localRegistry.getGraalVersion().match(Version.Match.Type.COMPATIBLE), false); - assertEquals("Just 1 version", 1, infos.size()); - - infos = registry.loadComponents("llvm-toolchain", localRegistry.getGraalVersion().match(Version.Match.Type.INSTALLABLE), false); - assertEquals("3 version equal or greater", 4, infos.size()); - } - - @Test - public void testAcceptsNewerPatchInstallVersion() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "21.0.0.0"); - setupCatalog("data/catalog21patch.properties"); - - textParams.add("ruby"); - textParams.add("python"); - - Collection infos = registry.loadComponents("ruby", localRegistry.getGraalVersion().match(Version.Match.Type.COMPATIBLE), false); - assertEquals("Release and patch ruby available", 2, infos.size()); - - paramIterable = new CatalogIterable(this, this); - Iterator params = paramIterable.iterator(); - assertTrue(params.hasNext()); - ComponentParam rubyParam = params.next(); - ComponentInfo rubyInfo = rubyParam.createMetaLoader().getComponentInfo(); - assertNotNull(rubyInfo); - assertEquals("org.graalvm.ruby", rubyInfo.getId()); - assertEquals("Only release is compatible", "21.0.0", rubyInfo.getVersion().displayString()); - - ComponentParam pythonParam = params.next(); - ComponentInfo pythonInfo = pythonParam.createMetaLoader().getComponentInfo(); - assertNotNull(pythonInfo); - assertEquals("org.graalvm.python", pythonInfo.getId()); - assertEquals("Patch can be installed", "21.0.0.2", pythonInfo.getVersion().displayString()); - } - - /** - * Checks that 20.3.1.1 will not downgrade to 20.3.1.0. - * - * @throws Exception - */ - @Test - public void testWillNotDowngradePatch() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "20.3.1.2"); - setupCatalog("data/catalog21patch.properties"); - - Collection infos; - infos = registry.loadComponents("llvm-toolchain", localRegistry.getGraalVersion().match(Version.Match.Type.INSTALLABLE), false); - assertEquals("4 version equal or greater", 4, infos.size()); - - infos = registry.loadComponents("llvm-toolchain", localRegistry.getGraalVersion().match(Version.Match.Type.COMPATIBLE), false); - assertEquals("2 version patch-compatible", 2, infos.size()); - } - - private static ComponentInfo findVersion(Collection versions, String vString) { - Version ver = Version.fromString(vString); - return versions.stream().filter( - c -> c.getVersion().equals(ver)).findFirst().orElse(null); - } - - /** - * Checks that older versions are acceptable. - * - * @throws Exception - */ - @Test - public void testAcceptCompatibleOlders() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "21.0.0.2"); - setupCatalog("data/catalog21patch.properties"); - - Collection infos; - - infos = registry.loadComponents("r", localRegistry.getGraalVersion().match(Version.Match.Type.INSTALLABLE), false); - assertEquals("1 older version ", 1, infos.size()); - assertEquals("21.0.0", infos.iterator().next().getVersion().displayString()); - - infos = registry.loadComponents("python", localRegistry.getGraalVersion().match(Version.Match.Type.INSTALLABLE), false); - assertEquals("2 older and current versions ", 2, infos.size()); - assertNotNull("21.0.0.2 present", findVersion(infos, "21.0.0.2")); - assertNotNull("21.0.0.0 present", findVersion(infos, "21.0.0.0")); - - textParams.add("python"); - - paramIterable = new CatalogIterable(this, this); - Iterator params = paramIterable.iterator(); - - ComponentParam pythonParam = params.next(); - ComponentInfo pythonInfo = pythonParam.createMetaLoader().getComponentInfo(); - assertNotNull(pythonInfo); - assertEquals("Current version offered", "21.0.0.2", pythonInfo.getVersion().toString()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InfoTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InfoTest.java deleted file mode 100644 index ab75df82040e..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InfoTest.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.List; -import java.util.Locale; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENTS; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_REQUIRES; -import org.graalvm.component.installer.DownloadURLIterable; -import org.graalvm.component.installer.MemoryFeedback; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONObject; -import org.graalvm.shadowed.org.json.JSONTokener; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class InfoTest extends CommandTestBase { - @Rule public final ProxyResource proxyResource = new ProxyResource(); - - private static final String GVM_VERSION = "1.0.0"; - private static final String STABILITY = "ComponentStabilityLevel_undefined"; - - private Version initVersion(String s) throws IOException { - Version v = Version.fromString(s); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, v.toString()); - Path catalogPath = dataFile("../repo/catalog.properties"); - RemoteCatalogDownloader downloader = new RemoteCatalogDownloader( - this, - this, - catalogPath.toUri().toURL()); - - registry = new CatalogContents(this, downloader.getStorage(), localRegistry); - paramIterable = new CatalogIterable(this, this); - return v; - } - - @Test - public void testInfoLocalComponent() throws Exception { - Path p = dataFile("truffleruby2.jar"); - textParams.add(p.toString()); - p = dataFile("../repo/python/1.0.0.0"); - textParams.add(p.toString()); - - InfoCommand cmd = new InfoCommand(); - cmd.init(this, this.withBundle(InfoCommand.class)); - cmd.collectComponents(); - - List comps = cmd.getComponents(); - assertEquals(2, comps.size()); - ComponentInfo ruby = comps.get(0); - assertEquals("org.graalvm.ruby", ruby.getId()); - ruby.getVersion().toString(); - assertEquals("1.0", ruby.getVersion().originalString()); - - ComponentInfo python = comps.get(1); - assertEquals("org.graalvm.python", python.getId()); - assertEquals("1.0.0.0", python.getVersion().originalString()); - } - - @Test - public void testInfoDownloadedComponent() throws Exception { - Path p = dataFile("truffleruby2.jar"); - options.put(Commands.OPTION_URLS, ""); - textParams.add(p.toUri().toString()); - - paramIterable = new DownloadURLIterable(this, this); - InfoCommand cmd = new InfoCommand(); - cmd.init(this, this.withBundle(InfoCommand.class)); - cmd.collectComponents(); - - List comps = cmd.getComponents(); - assertEquals(1, comps.size()); - ComponentInfo ruby = comps.get(0); - assertEquals("org.graalvm.ruby", ruby.getId()); - ruby.getVersion().toString(); - assertEquals("1.0", ruby.getVersion().originalString()); - } - - @Test - public void testInfoCompatibleComponents() throws Exception { - initVersion(GVM_VERSION); - - textParams.add("ruby"); - textParams.add("python"); - - InfoCommand cmd = new InfoCommand(); - cmd.init(this, this.withBundle(InfoCommand.class)); - cmd.collectComponents(); - - List comps = cmd.getComponents(); - assertEquals(2, comps.size()); - } - - @Test - public void testIncompatibleComponentInfo() throws Exception { - initVersion(GVM_VERSION); - - textParams.add("r"); - - InfoCommand cmd = new InfoCommand(); - cmd.init(this, this.withBundle(InfoCommand.class)); - cmd.collectComponents(); - - List comps = cmd.getComponents(); - assertEquals(1, comps.size()); - } - - @Test - public void testSpecificVersionInfo() throws Exception { - initVersion(GVM_VERSION); - - textParams.add("ruby=1.0.1.1"); - InfoCommand cmd = new InfoCommand(); - cmd.init(this, this.withBundle(InfoCommand.class)); - cmd.collectComponents(); - - List comps = cmd.getComponents(); - assertEquals(1, comps.size()); - - } - - @Test - public void testJSONOutput() throws Exception { - options.put(Commands.OPTION_JSON_OUTPUT, ""); - MemoryFeedback mf = new MemoryFeedback(); - this.delegateFeedback(mf); - initVersion(GVM_VERSION); - - textParams.add("ruby"); - textParams.add("python"); - - InfoCommand cmd = new InfoCommand(); - cmd.init(this, this.withBundle(InfoCommand.class)); - cmd.collectComponents(); - cmd.printComponents(); - - for (MemoryFeedback.Memory mem : mf) { - if (!mem.silent) { - JSONObject jo = new JSONObject(new JSONTokener(mem.key)); - JSONArray comps = jo.getJSONArray(JSON_KEY_COMPONENTS); - assertEquals(2, comps.length()); - for (int i = 0; i < comps.length(); ++i) { - JSONObject comp = comps.getJSONObject(i); - assertEquals(comp.toString(2), GVM_VERSION, comp.getString(CommonConstants.JSON_KEY_COMPONENT_GRAALVM)); - assertEquals(comp.toString(2), GVM_VERSION, comp.getString(CommonConstants.JSON_KEY_COMPONENT_VERSION)); - assertEquals(comp.toString(2), STABILITY, comp.getString(CommonConstants.JSON_KEY_COMPONENT_STABILITY)); - assertEquals(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_ORIGIN), comp.getString(CommonConstants.JSON_KEY_COMPONENT_FILENAME)); - assertTrue(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_ORIGIN).contains(comp.getString(CommonConstants.JSON_KEY_COMPONENT_ID).toLowerCase(Locale.ENGLISH))); - assertTrue(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_NAME) != null); - JSONObject req = comp.getJSONObject(JSON_KEY_COMPONENT_REQUIRES); - JSONArray reqNames = req.names(); - assertEquals(2, reqNames.length()); - for (int u = 0; u < reqNames.length(); ++u) { - String name = reqNames.getString(u); - assertEquals(comp.toString(2), storage.graalInfo.get(name), req.getString(name)); - } - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallTest.java deleted file mode 100644 index efb508ba8875..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallTest.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.File; -import org.graalvm.component.installer.CommandTestBase; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentIterable; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -public class InstallTest extends CommandTestBase { - @Rule public final ProxyResource proxyResource = new ProxyResource(); - - InstallCommand inst; - - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - files.add(dataFile("truffleruby2.jar").toFile()); - } - - @Test - public void testHelp() throws Exception { - class F extends FeedbackAdapter { - List outputKeys = new ArrayList<>(); - - @Override - public void output(String bundleKey, Object... params) { - outputKeys.add(bundleKey); - } - } - - F fe = new F(); - delegateFeedback(fe); - options.put(Commands.OPTION_HELP, ""); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - assertFalse(Files.list(targetPath).findFirst().isPresent()); - assertTrue(fe.outputKeys.get(0).toLowerCase().contains("help")); - } - - @Test - public void testDryRunInstall() throws IOException { - options.put(Commands.OPTION_DRY_RUN, ""); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - - assertFalse(Files.list(targetPath).findFirst().isPresent()); - } - - @Test - public void testValidateInstallFail() throws IOException { - options.put(Commands.OPTION_VALIDATE, ""); - - files.add(dataFile("truffleruby-i386.zip").toFile()); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - try { - inst.execute(); - fail("The second component should fail dependencies"); - } catch (DependencyException ex) { - // failed install - } - assertFalse(Files.list(targetPath).findFirst().isPresent()); - } - - private String errorKey; - private String msg; - - @Test - public void testIgnoreFailedInstall() throws IOException { - options.put(Commands.OPTION_VALIDATE, ""); - - files.add(dataFile("truffleruby-i386.zip").toFile()); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.setIgnoreFailures(true); - - delegateFeedback(new FeedbackAdapter() { - @Override - public void error(String key, Throwable t, Object... params) { - errorKey = key; - msg = t.getMessage(); - } - - }); - - inst.execute(); - assertFalse(Files.list(targetPath).findFirst().isPresent()); - assertEquals("VERIFY_Dependency_Failed", msg); - assertEquals("INSTALL_IgnoreFailedInstallation2", errorKey); - - } - - @Test - public void testDryRunForce() throws IOException { - options.put(Commands.OPTION_DRY_RUN, ""); - options.put(Commands.OPTION_FORCE, ""); - - files.add(dataFile("truffleruby-i386.zip").toFile()); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - assertFalse(Files.list(targetPath).findFirst().isPresent()); - } - - @Test - public void testValidateInstall() throws IOException { - options.put(Commands.OPTION_VALIDATE, ""); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - assertFalse(Files.list(targetPath).findFirst().isPresent()); - } - - @Test - public void testFailOnExistingComponent() throws IOException { - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - - options.put(Commands.OPTION_FAIL_EXISTING, ""); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - files.add(dataFile("truffleruby3.jar").toFile()); - - exception.expect(DependencyException.class); - exception.expectMessage("VERIFY_ComponentExists"); - inst.execute(); - } - - @Test - public void testSkipExistingComponent() throws IOException { - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - - File f = new File(folder.getRoot(), "inst"); - // bin/ruby is a symlink, which is skipped on Windows; so test the link's target: - File binRuby = SystemUtils.resolveRelative(f.toPath(), "jre/bin/ruby").toFile(); - assertTrue("Ruby must be installed", binRuby.exists()); - - Files.walk(f.toPath()).forEach((p) -> { - try { - if (!p.equals(f.toPath()) && Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)) { - Files.delete(p); - } - } catch (IOException ex) { - Logger.getLogger(InstallTest.class.getName()).log(Level.SEVERE, null, ex); - } - }); - - assertFalse("Ruby must be deleted", binRuby.exists()); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - files.add(dataFile("truffleruby3.jar").toFile()); - inst.execute(); - assertFalse("Component must not be processed", binRuby.exists()); - } - - ComponentIterable componentIterable; - - @Override - public ComponentIterable existingFiles() throws FailedOperationException { - if (componentIterable != null) { - return componentIterable; - } - return super.existingFiles(); - } - - @Test - public void testFailOnExistingFromCatalog() throws Exception { - ComponentInfo fakeInfo = new ComponentInfo("ruby", "Fake ruby", "1.0"); - storage.installed.add(fakeInfo); - - URL u = SystemUtils.toURL("test://graalvm.io/download/catalog"); - URL u2 = SystemUtils.toURL(u, "graalvm-ruby.zip"); - - Handler.bind(u.toString(), getClass().getResource("catalog")); - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - initCatalogIterable(u); - textParams.add("ruby"); - options.put(Commands.OPTION_FAIL_EXISTING, ""); - files.clear(); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - try { - inst.execute(); - } catch (DependencyException.Conflict ex) { - assertEquals("VERIFY_ComponentExists", ex.getMessage()); - } - - assertFalse(Handler.isVisited(u2)); - } - - private void initCatalogIterable(URL u) { - RemoteCatalogDownloader rcd = new RemoteCatalogDownloader( - this, - this, - u); - - registry = new CatalogContents(this, rcd.getStorage(), localRegistry); - componentIterable = new CatalogIterable(this, this); - } - - @Test - public void testSkipExistingFromCatalog() throws Exception { - ComponentInfo fakeInfo = new ComponentInfo("ruby", "Fake ruby", "1.0"); - storage.installed.add(fakeInfo); - - URL u = SystemUtils.toURL("test://graalvm.io/download/catalog"); - URL u2 = SystemUtils.toURL(u, "graalvm-ruby.zip"); - - Handler.bind(u.toString(), getClass().getResource("catalog")); - Handler.bind(u2.toString(), getClass().getResource("graalvm-ruby.zip")); - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - initCatalogIterable(u); - textParams.add("ruby"); - files.clear(); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - try { - inst.execute(); - } catch (DependencyException.Conflict ex) { - fail("Should not raise an error"); - } - - assertFalse("Should not touch the remote file", Handler.isVisited(u2)); - } - - @Test - public void testReplaceExistingComponent() throws IOException { - options.put(Commands.OPTION_REPLACE_COMPONENTS, ""); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - files.add(dataFile("truffleruby3.jar").toFile()); - - inst.execute(); - } - - @Test - public void testFailInstallCleanup() throws IOException { - Path offending = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Files.createDirectories(offending.getParent()); - Files.createFile(offending); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - try { - inst.execute(); - fail("Exception expected"); - } catch (IOException | FailedOperationException ex) { - // OK - } - Files.delete(offending); - Files.delete(offending.getParent()); // jre/bin - Files.delete(offending.getParent().getParent()); // jre - assertFalse(Files.list(targetPath).findFirst().isPresent()); - } - - @Test - public void testPostinstMessagePrinted() throws Exception { - AtomicBoolean printed = new AtomicBoolean(); - delegateFeedback(new FeedbackAdapter() { - @Override - public boolean verbatimOut(String aMsg, boolean beVerbose) { - if ("Postinst".equals(aMsg)) { - printed.set(true); - } - return super.verbatimOut(aMsg, beVerbose); - } - }); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - assertTrue("Postinst message must be printed", printed.get()); - } - - /** - * The exact message contents. Whitespaces are important, incl. newlines. - */ - private static final String GOLDEN_MESSAGE = "\n" + - "IMPORTANT NOTE:\n" + - "---------------\n" + - "The Ruby openssl C extension needs to be recompiled on your system to work with the installed libssl.\n" + - "Make sure headers for libssl are installed, see https://github.com/oracle/truffleruby/blob/master/doc/user/installing-libssl.md for details.\n" + - "Then run the following command:\n" + - " ${graalvm_home}/jre/languages/ruby/lib/truffle/post_install_hook.sh\n"; // exactly - // 6 - // spaces - // at - // the - // beginning - - @Test - public void testPostinstMessageFormat() throws Exception { - String[] formatted = new String[1]; - files.set(0, dataFile("postinst.jar").toFile()); - delegateFeedback(new FeedbackAdapter() { - @Override - public boolean verbatimOut(String aMsg, boolean beVerbose) { - if (aMsg.contains("Ruby openssl")) { // NOI18N - formatted[0] = aMsg; - } - return super.verbatimOut(aMsg, beVerbose); - } - }); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - assertNotNull("Postinst message must be printed", formatted[0]); - - String check = GOLDEN_MESSAGE.replace("${graalvm_home}", getGraalHomePath().toString()); - assertEquals(check, formatted[0]); - } - - /** - * Installs an a missing component from the same distribution. - * - * @throws Exception - */ - @Test - public void testInstallMissingComponent() throws Exception { - ComponentInfo fakeInfo = new ComponentInfo("ruby", "Fake ruby", "1.0"); - storage.installed.add(fakeInfo); - - } - - @Test - public void testRefuseNonAdminInstall() throws Exception { - options.put(Commands.OPTION_DRY_RUN, ""); - - storage.writableUser = "hero"; // NOI18N - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - exception.expect(FailedOperationException.class); - exception.expectMessage("ADMIN"); - - inst.execute(); - } - - private static final String BLOCKED_CONTENT = "This is a blocked file"; // NOI18N - private static final String INSTALL_CONTENT = "#!/usr/bin/env bash"; // NOI18N - - /** - * Checks that in the 'replace' scenario, the locked file is first scheduled for delete and then - * the new version for copy/moe to the original place. - */ - @Test - public void testReplaceExistingComponentWithLockedFiles() throws IOException { - options.put(Commands.OPTION_REPLACE_COMPONENTS, ""); - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - - inst.execute(); - - Path blockedFile = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby/bin/rake")); - Path copyDir = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby/bin.new")); - Path copyFile = copyDir.resolve("rake"); - - Files.write(blockedFile, Collections.singletonList(BLOCKED_CONTENT)); - - BlockedFileOps blockedOps = new BlockedFileOps(); - fileOps = blockedOps; - fileOps.init(this); - fileOps.setRootPath(targetPath); - - blockedOps.blockedPaths.add(blockedFile); - Path delayDeletes = folder.newFile("delayDeletes").toPath(); - Path copiedFiles = folder.newFile("copiedDirs").toPath(); - blockedOps.setDelayDeletedList(delayDeletes); - blockedOps.setCopyContents(copiedFiles); - - inst = new InstallCommand(); - inst.init(this, withBundle(InstallCommand.class)); - files.add(dataFile("truffleruby3.jar").toFile()); - - inst.execute(); - - // check that the original blocked file was not replaced: - assertEquals(BLOCKED_CONTENT, Files.readAllLines(blockedFile).get(0)); - assertEquals(INSTALL_CONTENT, Files.readAllLines(copyFile).get(0)); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallVersionsTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallVersionsTest.java deleted file mode 100644 index a005cab2696b..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallVersionsTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import static org.junit.Assert.assertEquals; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class InstallVersionsTest extends CommandTestBase { - @Rule public final ProxyResource proxyResource = new ProxyResource(); - - private InstallCommand cmd; - - private List installInfos = new ArrayList<>(); - private List installParams = new ArrayList<>(); - - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - - cmd = new InstallCommand() { - @Override - Installer createInstaller(ComponentParam p, MetadataLoader ldr) throws IOException { - installInfos.add(ldr.getComponentInfo()); - installParams.add(p); - Installer override = overrideCreateInstaller(p, ldr); - if (override == null) { - return super.createInstaller(p, ldr); - } else { - configureInstaller(override); - return override; - } - } - }; - cmd.init(this, withBundle(InstallCommand.class)); - } - - @SuppressWarnings("unused") - protected Installer overrideCreateInstaller(ComponentParam p, MetadataLoader ldr) throws IOException { - ComponentInfo partialInfo; - partialInfo = ldr.getComponentInfo(); - ldr.loadPaths(); - Archive a = null; - Installer inst = new Installer(this, getFileOperations(), partialInfo, getLocalRegistry(), - getRegistry(), a); - inst.setPermissions(ldr.loadPermissions()); - inst.setSymlinks(ldr.loadSymlinks()); - return inst; - - } - - private Version initVersion(String s) throws IOException { - Version v = Version.fromString(s); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, s); - Path catalogPath = dataFile("../repo/catalog.properties"); - RemoteCatalogDownloader downloader = new RemoteCatalogDownloader( - this, - this, - catalogPath.toUri().toURL()); - - registry = new CatalogContents(this, downloader.getStorage(), localRegistry); - paramIterable = new CatalogIterable(this, this); - return v; - } - - /** - * Installs a missing component from the same distribution. - */ - @Test - public void testMissingComponent() throws Exception { - initVersion("1.0.1.0"); - - textParams.add("python"); - cmd.prepareInstallation(); - assertEquals(1, installInfos.size()); - ComponentInfo ci = installInfos.get(0); - assertEquals("1.0.1.0", ci.getVersion().toString()); - } - - /** - * Installs a new component, but updated one, from a newer distribution. - */ - @Test - public void testInstallNewUpdatedComponent() throws Exception { - initVersion("1.0.1.0"); - - textParams.add("ruby"); - cmd.prepareInstallation(); - assertEquals(1, installInfos.size()); - ComponentInfo ci = installInfos.get(0); - assertEquals("1.0.1.1", ci.getVersion().toString()); - } - - /** - * Refuses to upgrade the core distribution. - */ - @Test - public void testRefuseCoreUpgrade() throws Exception { - initVersion("1.0.0.0"); - - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_UpgradeGraalVMCore"); - textParams.add("r"); - cmd.prepareInstallation(); - } - - @Test - public void testUnknownComponent() throws Exception { - initVersion("1.0.0.0"); - - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_UnknownComponentId"); - textParams.add("x"); - cmd.prepareInstallation(); - } - - @Test - public void testRefusedDowngrade() throws Exception { - initVersion("1.1.0.0"); - - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_UnknownComponentId"); - textParams.add("ruby"); - cmd.prepareInstallation(); - } - - @Test - public void testDowngradeToSpecificVersion() throws Exception { - initVersion("1.1.0.0"); - - exception.expect(FailedOperationException.class); - // catalogs do not even load obsolete versions - exception.expectMessage("REMOTE_UnknownComponentId"); - textParams.add("ruby=1.0.0.0"); - cmd.prepareInstallation(); - } - - @Test - public void testRefuseExplicitUpgrade() throws Exception { - initVersion("1.0.1.0"); - - exception.expect(DependencyException.Mismatch.class); - exception.expectMessage("VERIFY_UpdateGraalVM"); - textParams.add("python=1.1.0.0"); - cmd.prepareInstallation(); - } - - @Test - public void testFailOneOfComponents() throws Exception { - initVersion("1.0.1.0"); - textParams.add("ruby"); - textParams.add("python=1.1.0.0"); - exception.expect(DependencyException.Mismatch.class); - exception.expectMessage("VERIFY_UpdateGraalVM"); - cmd.prepareInstallation(); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallerTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallerTest.java deleted file mode 100644 index fab5c1947a49..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/InstallerTest.java +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.nio.file.DirectoryNotEmptyException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.jar.JarFile; - -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.jar.JarArchive; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.os.DefaultFileOperations; -import org.graalvm.component.installer.os.WindowsFileOperations; -import org.graalvm.component.installer.persist.ComponentPackageLoader; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; - -public class InstallerTest extends TestBase { - @Rule public ExpectedException exception = ExpectedException.none(); - protected JarArchive componentJarFile; - @Rule public TemporaryFolder folder = new TemporaryFolder(); - - private Path targetPath; - - private MockStorage storage; - private ComponentRegistry registry; - private ComponentPackageLoader loader; - private Installer installer; - private ComponentInfo componentInfo; - - protected FileOperations fileOps; - - private void setupComponentInstall(String relativePath) throws IOException { - File f = dataFile(relativePath).toFile(); - JarFile jf = new JarFile(f); - - loader = new JarMetaLoader(jf, this); - componentInfo = loader.createComponentInfo(); - - componentJarFile = new JarArchive(jf); - - loader.loadPaths(); - installer = new Installer(fb(), fileOps, componentInfo, registry, registry, componentJarFile); - installer.setInstallPath(targetPath); - installer.setLicenseRelativePath(SystemUtils.fromCommonRelative(loader.getLicensePath())); - } - - private Feedback fb() { - return withBundle(Installer.class); - } - - public InstallerTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() throws IOException { - targetPath = folder.newFolder("inst").toPath(); - storage = new MockStorage(); - registry = new ComponentRegistry(this, storage); - fileOps = SystemUtils.isWindows() ? new WindowsFileOperations() : new DefaultFileOperations(); - fileOps.init(this); - fileOps.setRootPath(targetPath); - } - - @After - public void tearDown() throws Exception { - if (componentJarFile != null) { - componentJarFile.close(); - } - } - - @Test - public void testFailRemoteComponentExisting() throws IOException { - setupComponentInstall("truffleruby2.jar"); - ComponentInfo fakeInfo = new ComponentInfo("org.graalvm.ruby", "Fake ruby", "1.0"); - storage.installed.add(fakeInfo); - exception.expect(DependencyException.Conflict.class); - exception.expectMessage("VERIFY_ComponentExists"); - installer.setFailOnExisting(true); - installer.validateRequirements(); - } - - /** - * Checks that the component will be uninstalled before installing a new one. - * - * Disabled; the uninstall logic is now implemented by InstallCommand and tested by InstallTest. - * - * @Test public void testSetReplaceComponents() throws IOException { - * setupComponentInstall("truffleruby2.jar"); ComponentInfo fakeInfo = new - * ComponentInfo("org.graalvm.ruby", "Fake ruby", "0.32"); - * storage.installed.add(fakeInfo); - * - * installer.setReplaceComponents(true); installer.validateRequirements(); - * installer.install(); } - */ - - @Test - public void testFailOnExistingComponent() throws IOException { - setupComponentInstall("truffleruby2.jar"); - // the version has to be the same as the installed component, or newer so that installer - // will not attempt to replace it. - ComponentInfo fakeInfo = new ComponentInfo("org.graalvm.ruby", "Fake ruby", "1.1"); - storage.installed.add(fakeInfo); - - exception.expect(DependencyException.Conflict.class); - exception.expectMessage("VERIFY_ComponentExists"); - installer.setFailOnExisting(true); - installer.validateRequirements(); - } - - @Test - public void testDontFailOnComponentUpdate() throws IOException { - setupComponentInstall("truffleruby2.jar"); - // the version has to be the same as the installed component, or newer so that installer - // will not attempt to replace it. - ComponentInfo fakeInfo = new ComponentInfo("org.graalvm.ruby", "Fake ruby", "0.99"); - storage.installed.add(fakeInfo); - - installer.setFailOnExisting(true); - installer.validateRequirements(); - } - - @Test - public void testSkipExistingComponent() throws IOException { - setupComponentInstall("truffleruby2.jar"); - ComponentInfo fakeInfo = new ComponentInfo("org.graalvm.ruby", "Fake ruby", "1.0"); - storage.installed.add(fakeInfo); - - installer.setFailOnExisting(false); - assertFalse("Must refuse installation", installer.validateAll()); - } - - @Test - public void testAcceptComponentUpgrade() throws IOException { - setupComponentInstall("truffleruby2.jar"); - ComponentInfo fakeInfo = new ComponentInfo("org.graalvm.ruby", "Fake ruby", "0.32"); - storage.installed.add(fakeInfo); - - installer.setFailOnExisting(false); - assertTrue("Must refuse installation", installer.validateAll()); - } - - /** - * Test of uninstall method, of class Installer. - */ - @Test - public void testUninstall() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - - ComponentInfo savedInfo = installer.getComponentInfo(); - - // now uninstall, fileName a new installer. - Uninstaller uninstaller = new Uninstaller(fb(), fileOps, savedInfo, registry); - uninstaller.setInstallPath(targetPath); - uninstaller.uninstallContent(); - - assertFalse("All files should be removed after uninstall", - Files.list(targetPath).findAny().isPresent()); - } - - /** - * Test of uninstall method, of class Installer. - */ - @Test - public void testUninstallFailsOnExtraFile() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - - ComponentInfo savedInfo = installer.getComponentInfo(); - - Path langPath = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby")); - Path roPath = langPath.resolve(SystemUtils.fromCommonString("doc/user")); - // and add a new file to that dir: - Path uf = roPath.resolve(SystemUtils.fileName("userFile.txt")); - Files.write(uf, Arrays.asList("This file", "Should vanish")); - - exception.expect(DirectoryNotEmptyException.class); - exception.expectMessage("jre/languages/ruby/doc/user".replace(SystemUtils.DELIMITER, File.separator)); - // now uninstall, fileName a new installer. - Uninstaller uninstaller = new Uninstaller(fb(), fileOps, savedInfo, registry); - uninstaller.setInstallPath(targetPath); - uninstaller.uninstallContent(); - - fail("Shouldn't be reached"); - } - - @Test - public void testRecursiveDelete() throws Exception { - // install just to get the component structure - setupComponentInstall("truffleruby2.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - PreRemoveProcess preRemove = new PreRemoveProcess(targetPath, fileOps, this); - Path langPath = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby")); - preRemove.deleteContentsRecursively(langPath); - - // the root dir still exists - assertTrue(Files.exists(langPath)); - // but is empty: - - assertFalse("All files should be removed by recursive delete", - Files.list(langPath).findAny().isPresent()); - } - - @Test - public void testRecursiveDeleteWithReadonlyFiles() throws Exception { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - - // install just to get the component structure - setupComponentInstall("truffleruby2.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - Path langPath = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby")); - - Path roPath = langPath.resolve(SystemUtils.fromCommonString("doc/legal")); - Files.setPosixFilePermissions(roPath, PosixFilePermissions.fromString("r-xr-xr-x")); - - PreRemoveProcess preRemove = new PreRemoveProcess(targetPath, fileOps, this); - preRemove.deleteContentsRecursively(langPath); - // the root dir still exists - assertTrue(Files.exists(langPath)); - // but is empty: - - assertFalse("All files should be removed by recursive delete", - Files.list(langPath).findAny().isPresent()); - } - - @Test - public void testUninstallComponentWithROFiles() throws Exception { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - setupComponentInstall("trufflerubyRO.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - - ComponentInfo savedInfo = installer.getComponentInfo(); - - // now uninstall, fileName a new installer. - Uninstaller uninstaller = new Uninstaller(fb(), fileOps, savedInfo, registry); - uninstaller.setInstallPath(targetPath); - uninstaller.uninstallContent(); - - assertFalse("All files should be removed after uninstall", - Files.list(targetPath).findAny().isPresent()); - } - - @Test - public void testUninstallComponentWithUserROFiles() throws Exception { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - setupComponentInstall("trufflerubyWork.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - - ComponentInfo savedInfo = installer.getComponentInfo(); - - Path langPath = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby")); - Path roPath = langPath.resolve(SystemUtils.fromCommonString("doc/user")); - - // and add a new file to that dir: - Path uf = roPath.resolve(SystemUtils.fileName("userFile.txt")); - Files.write(uf, Arrays.asList("This file", "Should vanish")); - Files.setPosixFilePermissions(uf, PosixFilePermissions.fromString("r--r-----")); - Files.setPosixFilePermissions(roPath, PosixFilePermissions.fromString("r-xr-xr-x")); - - // now uninstall, fileName a new installer. - Uninstaller uninstaller = new Uninstaller(fb(), fileOps, savedInfo, registry); - uninstaller.setInstallPath(targetPath); - uninstaller.uninstallContent(); - - assertFalse("All files should be removed after uninstall", - Files.list(targetPath).findAny().isPresent()); - } - - /** - * Checks that the uninstall does not fail even though it cannot delete something. - */ - @Test - public void testSetIgnoreFailedDeletions() throws IOException { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - setupComponentInstall("truffleruby2.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - - ComponentInfo savedInfo = installer.getComponentInfo(); - - // make some directory readonly - Path p = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby/doc/legal")); - Files.setPosixFilePermissions(p, PosixFilePermissions.fromString("r--r--r--")); - - // now uninstall, fileName a new installer. - Uninstaller uninstaller = new Uninstaller(fb(), fileOps, savedInfo, registry); - uninstaller.setInstallPath(targetPath); - uninstaller.setIgnoreFailedDeletions(true); - uninstaller.uninstall(); - } - - /** - * Checks that the uninstall does not fail even though it cannot delete something. - */ - @Test - public void testFailedDeletionAborts() throws IOException { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - setupComponentInstall("truffleruby2.jar"); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - // install - installer.install(); - - ComponentInfo savedInfo = installer.getComponentInfo(); - - // make some directory readonly - Path p = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby/doc/legal")); - Files.setPosixFilePermissions(p, PosixFilePermissions.fromString("r--r--r--")); - - // now uninstall, fileName a new installer. - Uninstaller uninstaller = new Uninstaller(fb(), fileOps, savedInfo, registry); - uninstaller.setInstallPath(targetPath); - - exception.expect(IOException.class); - uninstaller.uninstall(); - } - - /** - * Checks that requirements are properly validated. - */ - @Test - public void testValidateRequirementsSuccess() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.validateRequirements(); - } - - @Test - public void testValidateRequirementsGraalVersion() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.getComponentInfo().addRequiredValue(CommonConstants.CAP_GRAALVM_VERSION, "0.33"); - - exception.expect(DependencyException.class); - exception.expectMessage("VERIFY_UpdateGraalVM"); - installer.validateRequirements(); - } - - @Test - public void testValidateRequirementsGraalVersion2() throws Exception { - - setupComponentInstall("truffleruby2.jar"); - // simulate different version of Graal installation - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.30"); - - exception.expect(DependencyException.class); - exception.expectMessage("VERIFY_UpdateGraalVM"); - installer.validateRequirements(); - } - - /** - * Checks that components with explicit java requirement fail on non-matching graalvm. - */ - @Test - public void testValidateRequirementsDifferentJava() throws Exception { - setupComponentInstall("truffleruby2-11.jar"); - - exception.expect(DependencyException.class); - exception.expectMessage("VERIFY_Dependency_Failed"); - installer.validateRequirements(); - } - - /** - * Checks that components with explicit java requirement succeeds on the correct GraalVM. - */ - @Test - public void testValidateRequirementsJavaMatches() throws Exception { - setupComponentInstall("truffleruby2-11.jar"); - storage.graalInfo.put(CommonConstants.CAP_JAVA_VERSION, "11"); - installer.validateRequirements(); - } - - /** - * Checks that the component is installed despite the requirements. - */ - @Test - public void testSetIgnoreRequirements() throws Exception { - setupComponentInstall("truffleruby2-11.jar"); - // simulate different version of Graal installation - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.30"); - - installer.setIgnoreRequirements(true); - installer.validateRequirements(); - } - - /** - * Test of install method, of class Installer. - */ - @Test - public void testInstall() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.setSymlinks(loader.loadSymlinks()); - installer.setPermissions(loader.loadPermissions()); - installer.install(); - - Path jreRuby = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Path binRuby = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - - assertTrue(Files.exists(jreRuby)); - - // symlink is skipped on Windows OS - if (!isWindows()) { - assertTrue(Files.exists(binRuby)); - } - - if (!System.getProperty("os.name").toLowerCase().contains("windows")) { - assertTrue(Files.isExecutable(jreRuby)); - assertTrue(Files.isSymbolicLink(binRuby)); - } - - // checks that everything is properly reverted - installer.revertInstall(); - - assertFalse("No files should be created under dry run", - Files.list(targetPath).findAny().isPresent()); - } - - /** - * Test of installOneFile method, of class Installer. - */ - @Test - public void testInstallOneRegularFile() throws Exception { - setupComponentInstall("truffleruby2.jar"); - /* - * inst.setPermissions(ldr.loadPermissions()); inst.setSymlinks(ldr.loadSymlinks()); - */ - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/bin/ruby"); - Path resultPath = installer.installOneFile(installer.translateTargetPath(entry), entry); - Path relative = targetPath.relativize(resultPath); - assertEquals(entry.getName(), SystemUtils.toCommonPath(relative)); - - Path check = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - // assume directories are also created - assertTrue(Files.exists(check)); - assertEquals(entry.getSize(), Files.size(check)); - - // check that the installation is reverted - installer.revertInstall(); - - assertFalse(Files.exists(check)); - // two levels of directories should have been created - assertFalse(Files.exists(check.getParent())); - assertFalse(Files.exists(check.getParent().getParent())); - } - - /** - * Check that if the same file is found and skipped, it will not revert on installation abort. - */ - @Test - public void testInstallExistingFileWillNotRevert() throws Exception { - setupComponentInstall("truffleruby2.jar"); - /* - * inst.setPermissions(ldr.loadPermissions()); inst.setSymlinks(ldr.loadSymlinks()); - */ - Path existing = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Files.createDirectories(existing.getParent()); - Files.copy(dataFile("ruby"), existing); - - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/bin/ruby"); - Path resultPath = installer.installOneFile(installer.translateTargetPath(entry), entry); - Path relative = targetPath.relativize(resultPath); - assertEquals(entry.getName(), SystemUtils.toCommonPath(relative)); - - Path check = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - // assume directories are also created - assertTrue(Files.exists(check)); - assertEquals(entry.getSize(), Files.size(check)); - - // check that the installation is reverted - installer.revertInstall(); - - // MUST still exist, the installe did not fileName it - assertTrue(Files.exists(check)); - } - - /** - * Check that if the same file is found and skipped, it will not revert on installation abort. - */ - @Test - public void testInstallOverwrittemFileWillNotRevert() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.setReplaceDiferentFiles(true); - - /* - * inst.setPermissions(ldr.loadPermissions()); inst.setSymlinks(ldr.loadSymlinks()); - */ - Path existing = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Files.createDirectories(existing.getParent()); - Files.copy(dataFile("ruby2"), existing); - - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/bin/ruby"); - Path resultPath = installer.installOneFile(installer.translateTargetPath(entry), entry); - Path relative = targetPath.relativize(resultPath); - assertEquals(entry.getName(), SystemUtils.toCommonPath(relative)); - - Path check = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - // assume directories are also created - assertTrue(Files.exists(check)); - assertEquals(entry.getSize(), Files.size(check)); - - // check that the installation is reverted - installer.revertInstall(); - - // MUST still exist, the installe did not fileName it - assertTrue(Files.exists(check)); - } - - /** - * Checks that an empty directory is installed. - */ - @Test - public void testInstallOneDirectory() throws Exception { - setupComponentInstall("truffleruby2.jar"); - - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/bin/"); - installer.installOneEntry(entry); - - Path check = targetPath.resolve(SystemUtils.fromCommonString("jre/bin")); - // assume directories are also created - assertTrue(Files.exists(check)); - assertTrue(Files.isDirectory(check)); - - // rollback - installer.revertInstall(); - - assertFalse(Files.exists(check)); - } - - /** - * Checks that if a directory already exists, it will not be reverted on failed install. - */ - @Test - public void testInstallExistingDirectoryWillNotRevert() throws Exception { - setupComponentInstall("truffleruby2.jar"); - - Path existing = targetPath.resolve(SystemUtils.fromCommonString("jre/bin")); - Files.createDirectories(existing); - - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/bin/"); - installer.installOneEntry(entry); - - Path check = targetPath.resolve(SystemUtils.fromCommonString("jre/bin")); - // assume directories are also created - assertTrue(Files.exists(check)); - assertTrue(Files.isDirectory(check)); - - // rollback - installer.revertInstall(); - - assertTrue(Files.exists(check)); - } - - /** - * Checks that permissions are correctly changed. Works only on UNIXes. - */ - @Test - public void testProcessPermissions() throws Exception { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - - setupComponentInstall("truffleruby3.jar"); - installer.unpackFiles(); - // check the executable file has no permissions - Path check = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - assertFalse(Files.isExecutable(check)); - installer.processPermissions(); - // still nothing, no permissions were set - assertFalse(Files.isExecutable(check)); - installer.setPermissions(loader.loadPermissions()); - installer.processPermissions(); - assertTrue(Files.isExecutable(check)); - assertTrue(Files.isExecutable(targetPath.resolve( - SystemUtils.fromCommonString("jre/languages/ruby/bin/ri")))); - } - - /** - * Checks correct creation of symlinks. Works only on UNIXes. - */ - @Test - public void testCreateSymlinks() throws Exception { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - setupComponentInstall("truffleruby2.jar"); - installer.unpackFiles(); - - // check the executable file has no permissions - Path check = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - assertFalse(Files.exists(check)); - - installer.setSymlinks(loader.loadSymlinks()); - installer.createSymlinks(); - - assertTrue(Files.exists(check)); - assertTrue(Files.isSymbolicLink(check)); - Path target = Files.readSymbolicLink(check); - - Path resolved = targetPath.relativize(check.resolveSibling(target).normalize()); - assertEquals("jre/bin/ruby", SystemUtils.toCommonPath(resolved)); - - installer.revertInstall(); - - assertFalse(Files.exists(check)); - } - - /** - * Test of checkFileReplacement method, of class Installer. - */ - @Test - public void testCheckFileReplacementSame() throws Exception { - setupComponentInstall("truffleruby2.jar"); - - Path existingOrig = dataFile("ruby"); - - Path existing = expandedFolder.newFile("testCheckFileReplacementSame-ruby").toPath(); - // regardless of CRLF, join lines with \n, write as bytes to bypass CRLF conversion. - Files.write(existing, (String.join("\n", Files.readAllLines(existingOrig)) + "\n").getBytes("UTF-8")); - - Archive.FileEntry je = componentJarFile.getJarEntry("jre/bin/ruby"); - - // should pass: - installer.checkFileReplacement(existing, je); - } - - /** - * Test of checkFileReplacement method, of class Installer. - */ - @Test - public void testCheckFileReplacementDifferent() throws Exception { - setupComponentInstall("truffleruby2.jar"); - - Path existing = dataFile("ruby2"); - Archive.FileEntry je = componentJarFile.getJarEntry("jre/bin/ruby"); - - // should fail: - exception.expect(FailedOperationException.class); - exception.expectMessage("INSTALL_ReplacedFileDiffers"); - installer.checkFileReplacement(existing, je); - } - - /** - * Test of checkFileReplacement method, of class Installer. - */ - @Test - public void testCheckFileReplacementForced() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.setReplaceDiferentFiles(true); - - Path existing = dataFile("ruby2"); - Archive.FileEntry je = componentJarFile.getJarEntry("jre/bin/ruby"); - - // should succeed: - installer.checkFileReplacement(existing, je); - } - - /** - * Checks that the install does not do anything if dry run is enabled. - */ - @Test - public void testSetDryRun() throws IOException { - setupComponentInstall("truffleruby2.jar"); - installer.setDryRun(true); - installer.setPermissions(loader.loadPermissions()); - installer.setSymlinks(loader.loadSymlinks()); - - installer.install(); - - assertFalse("No files should be created under dry run", - Files.list(targetPath).findAny().isPresent()); - } - - @Test - public void testValidateFiles() throws Exception { - setupComponentInstall("truffleruby2.jar"); - installer.validateFiles(); - - installer.setSymlinks(loader.loadSymlinks()); - installer.setPermissions(loader.loadPermissions()); - - installer.validateAll(); - } - - @Test - public void testValidateOverwriteDirectoryWithFile() throws IOException { - setupComponentInstall("truffleruby2.jar"); - Path offending = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Files.createDirectories(offending); - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/bin/ruby"); - - exception.expect(IOException.class); - exception.expectMessage("INSTALL_OverwriteWithFile"); - installer.validateOneEntry( - installer.translateTargetPath(entry), entry); - } - - @Test - public void testValidateOverwriteFileWithDirectory() throws IOException { - setupComponentInstall("truffleruby2.jar"); - Path offending = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby")); - Files.createDirectories(offending.getParent()); - Files.createFile(offending); - Archive.FileEntry entry = componentJarFile.getJarEntry("jre/languages/ruby/"); - - exception.expect(IOException.class); - exception.expectMessage("INSTALL_OverwriteWithDirectory"); - installer.validateOneEntry( - installer.translateTargetPath(entry), entry); - } - - @Test - public void testRevertInstallFailureFile() throws Exception { - if (isWindows()) { - return; - } - setupComponentInstall("truffleruby2.jar"); - Path jreRuby = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Files.createDirectories(jreRuby.getParent()); - installer.install(); - - assertTrue(Files.exists(jreRuby)); - - Files.setPosixFilePermissions( - jreRuby.getParent(), PosixFilePermissions.fromString("r-xr-xr-x")); - // checks that everything is properly reverted - try { - class FD extends FeedbackAdapter { - List errors = new ArrayList<>(); - - @Override - public void error(String key, Throwable t, Object... params) { - errors.add(key); - } - - } - FD fd = new FD(); - delegateFeedback(fd); - installer.revertInstall(); - // must report something - assertTrue(fd.errors.isEmpty()); - assertFalse(Files.exists(jreRuby)); - } finally { - Files.setPosixFilePermissions( - jreRuby.getParent(), PosixFilePermissions.fromString("rwxrwxrwx")); - } - } - - @Test - public void testRevertInstallFailureDir() throws Exception { - if (isWindows()) { - return; - } - setupComponentInstall("truffleruby2.jar"); - Path jreLang = targetPath.resolve(SystemUtils.fromCommonString("jre/languages")); - Files.createDirectories(jreLang); - installer.install(); - - assertTrue(Files.exists(jreLang)); - - Files.setPosixFilePermissions( - jreLang, PosixFilePermissions.fromString("r-xr-xr-x")); - // checks that everything is properly reverted - try { - class FD extends FeedbackAdapter { - List errors = new ArrayList<>(); - - @Override - public void error(String key, Throwable t, Object... params) { - errors.add(key); - } - - } - FD fd = new FD(); - delegateFeedback(fd); - installer.revertInstall(); - // must report something - assertTrue(fd.errors.isEmpty()); - assertFalse(Files.list(jreLang).iterator().hasNext()); - } finally { - Files.setPosixFilePermissions( - jreLang, PosixFilePermissions.fromString("rwxrwxrwx")); - } - } - - @Test - public void testUnpackExistingSymlinks() throws Exception { - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - return; - } - setupComponentInstall("truffleruby2.jar"); - Path offending = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - Files.createDirectories(offending.getParent()); - Files.createSymbolicLink(offending, SystemUtils.fromCommonString("../jre/bin/ruby")); - - Path offending2 = targetPath.resolve(SystemUtils.fromCommonString("jre/languages/ruby/bin/ruby")); - Files.createDirectories(offending2.getParent()); - Files.createSymbolicLink(offending2, SystemUtils.fileName("xxx")); - - installer.setReplaceDiferentFiles(true); - installer.setSymlinks(loader.loadSymlinks()); - installer.createSymlinks(); - - List paths = componentInfo.getPaths(); - assertTrue(paths.contains("bin/ruby")); - assertTrue(paths.contains("jre/languages/ruby/bin/ruby")); - - assertEquals(SystemUtils.fileName("truffleruby"), Files.readSymbolicLink(offending2)); - } - - @Test - public void testFailOverwriteFileWithSymlink() throws Exception { - setupComponentInstall("truffleruby2.jar"); - // prepare offending symlink going elsewhere - - Path offending = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - Files.createDirectories(offending.getParent()); - Files.createFile(offending); - - exception.expect(IOException.class); - exception.expectMessage("INSTALL_OverwriteWithLink"); - installer.setSymlinks(loader.loadSymlinks()); - installer.validateSymlinks(); - } - - @Test - public void testOverwriteFileWithSymlink() throws Exception { - if (isWindows()) { - return; - } - - setupComponentInstall("truffleruby2.jar"); - // prepare offending symlink going elsewhere - - Path offending = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - Files.createDirectories(offending.getParent()); - Files.createSymbolicLink(offending, targetPath.resolve(SystemUtils.fromCommonString("../jre/bin/ruby"))); - - installer.setReplaceDiferentFiles(true); - installer.setSymlinks(loader.loadSymlinks()); - installer.validateSymlinks(); - } - - @Test - public void testFailOverwriteOtherSymlink() throws Exception { - if (isWindows()) { - return; - } - - setupComponentInstall("truffleruby2.jar"); - // prepare offending symlink going elsewhere - - Path offending = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - Files.createDirectories(offending.getParent()); - Files.createSymbolicLink(offending, targetPath.resolve(SystemUtils.fromCommonString("../x"))); - - exception.expect(FailedOperationException.class); - exception.expectMessage("INSTALL_ReplacedFileDiffers"); - installer.setSymlinks(loader.loadSymlinks()); - installer.validateSymlinks(); - } - - @Test - public void testOverwriteOtherSymlink() throws Exception { - if (isWindows()) { - return; - } - setupComponentInstall("truffleruby2.jar"); - // prepare offending symlink going elsewhere - - Path offending = targetPath.resolve(SystemUtils.fromCommonString("bin/ruby")); - Files.createDirectories(offending.getParent()); - Files.createSymbolicLink(offending, targetPath.resolve(SystemUtils.fromCommonString("../x"))); - - installer.setSymlinks(loader.loadSymlinks()); - installer.setReplaceDiferentFiles(true); - installer.validateSymlinks(); - } - - /** - * Checks that installer blocks files in component storage directory, but not in subdirs. - */ - @Test - public void testComponentRegistryNotWrittenTo() throws Exception { - setupComponentInstall("trufflerubyWork.jar"); - installer.setSymlinks(loader.loadSymlinks()); - installer.setPermissions(loader.loadPermissions()); - installer.install(); - - Path p = targetPath.resolve(SystemUtils.fromCommonString(CommonConstants.PATH_COMPONENT_STORAGE)); - Path rubyMeta = p.resolve("org.graalvm.ruby.meta"); - Path other = p.resolve("other"); - Path pythonList = p.resolve("python.list"); - - assertFalse(Files.exists(rubyMeta)); - assertFalse(Files.exists(pythonList)); - - assertTrue(Files.exists(other)); - } - - private static final String BLOCKED_CONTENT = "This is a blocked file"; // NOI18N - private static final String INSTALL_CONTENT = "Test content: ./jre/bin/ruby"; // NOI18N - - /** - * Checks that install that wants to overwrite a 'blocked' file will succeed, but record the - * file as one which has to be copied over afterwards. - */ - @Test - public void testOverwriteBlockedFile() throws Exception { - Path blockedFile = targetPath.resolve(SystemUtils.fromCommonString("jre/bin/ruby")); - Files.createDirectories(blockedFile.getParent()); - Files.write(blockedFile, Arrays.asList(BLOCKED_CONTENT)); - - BlockedFileOps blockedOps = new BlockedFileOps(); - fileOps = blockedOps; - fileOps.init(this); - fileOps.setRootPath(targetPath); - - blockedOps.blockedPaths.add(blockedFile); - Path delayDeletes = folder.newFile("delayDeletes").toPath(); - Path copiedFiles = folder.newFile("copiedDirs").toPath(); - blockedOps.setDelayDeletedList(delayDeletes); - blockedOps.setCopyContents(copiedFiles); - - setupComponentInstall("trufflerubyWork.jar"); - installer.setSymlinks(loader.loadSymlinks()); - installer.setPermissions(loader.loadPermissions()); - installer.setReplaceDiferentFiles(true); - installer.install(); - - assertTrue(blockedOps.getDelayDeletedPaths().isEmpty()); - Map copies = blockedOps.getCopiedPaths(); - Path copyDir = targetPath.resolve(SystemUtils.fromCommonString("jre/bin.new")); - Path copyFile = copyDir.resolve("ruby"); - assertEquals(1, copies.size()); - assertEquals(copyDir, copies.get(blockedFile.getParent())); - assertEquals(BLOCKED_CONTENT, Files.readAllLines(blockedFile).get(0)); - assertEquals(INSTALL_CONTENT, Files.readAllLines(copyFile).get(0)); - - // check that the logfiles are OK - assertTrue(blockedOps.flush()); - - // no file is delay-deleted - assertEquals(0, Files.readAllLines(delayDeletes).size()); - - // one directory is post-moved - String l = blockedFile.getParent().toString() + "|" + copyDir.toString(); - assertEquals(l, Files.readAllLines(copiedFiles).get(0)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/LicensePresenterTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/LicensePresenterTest.java deleted file mode 100644 index afe77ff1fa16..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/LicensePresenterTest.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.jar.JarFile; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.UserAbortException; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.DirectoryMetaLoader; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class LicensePresenterTest extends CommandTestBase { - MetadataLoader loader; - Path dirPath; - Map> licenseIDs = new LinkedHashMap<>(); - - ComponentInfo licensedInfo; - - ComponentInfo createLicensedComponentInfo() throws IOException { - Path p = dataFile("licensetest.jar"); - JarFile jf = new JarFile(p.toFile()); - loader = new JarMetaLoader(jf, this); - licensedInfo = loader.completeMetadata(); - - return licensedInfo; - } - - private void initLoader(String f) throws IOException { - if (loader != null) { - loader.close(); - } - Path p = expandedFolder.getRoot().toPath().resolve(testName.getMethodName()); - if (!Files.isDirectory(p)) { - Files.createDirectory(p); - } - dirPath = dataFile(f); - loader = DirectoryMetaLoader.create(dirPath, this); - licensedInfo = loader.completeMetadata(); - } - - @Test - public void testAcceptedLicensesWillBeSuppressed() throws Exception { - initLoader("license.ruby"); - - LicensePresenter p = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - licenseIDs.put(loader.getLicenseID(), new ArrayList<>(Arrays.asList(loader))); - Map comps = new HashMap<>(); - comps.put(loader.getLicenseID(), new Date()); - this.storage.acceptedLicenses.put(loader.getComponentInfo().getId(), comps); - p.init(); - assertTrue(p.isFinished()); - } - - @Test - public void testLicensesWillShow() throws Exception { - initLoader("license.ruby"); - - LicensePresenter p = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - licenseIDs.put(loader.getLicenseID(), new ArrayList<>(Arrays.asList(loader))); - - p.init(); - assertFalse(p.isFinished()); - assertEquals(LicensePresenter.State.SINGLE, p.getState()); - } - - class LicFeedback extends FeedbackAdapter { - boolean questionAsked; - String answer; - String licenseQuestion; - - LicFeedback(String licenseQuestion) { - this.licenseQuestion = licenseQuestion; - } - - @Override - public String l10n(String key, Object... params) { - if (key.contains("AcceptPrompt")) { - return reallyl10n(key, params); - } - return super.l10n(key, params); - } - - @Override - public String acceptLine(boolean yes) { - return answer; - } - - @Override - public void output(String bundleKey, Object... params) { - if (bundleKey.equals(licenseQuestion)) { - questionAsked = true; - } - super.output(bundleKey, params); - } - } - - void addLoader(String rpmName) throws Exception { - initLoader(rpmName); - licenseIDs.computeIfAbsent(loader.getLicenseID(), (n) -> new ArrayList<>()).add(loader); - } - - LicensePresenter pres; - LicFeedback licF; - - /** - * Checks that single license will display prompt and accepts "Read". - */ - @Test - public void testSingleLicenseDisplaysQuestion() throws Exception { - addLoader("license.ruby"); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - - licF = new LicFeedback("INSTALL_AcceptLicense"); - delegateFeedback(licF); - licF.answer = "r"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - assertTrue(licF.questionAsked); - - pres.init(); - licF.answer = "R"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - - pres.init(); - licF.answer = "Read"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - - pres.init(); - licF.answer = "rEaD"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - } - - /** - * Any other answer than Y or R will abort the operation. - */ - public void testSingleLicenseUserAbort() throws Exception { - addLoader("license.ruby"); - - LicensePresenter p = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - p.init(); - - LicFeedback d = new LicFeedback("INSTALL_AcceptLicense"); - delegateFeedback(d); - d.answer = "a"; - exception.expect(UserAbortException.class); - p.singleStep(); - } - - /** - * License can be accepted even without reading the text. - */ - @Test - public void testSingleLicenseAcceptNoRead() throws Exception { - addLoader("license.ruby"); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - - LicFeedback d = new LicFeedback("INSTALL_AcceptLicense"); - delegateFeedback(d); - d.answer = "y"; - pres.singleStep(); - assertTrue(pres.isFinished()); - assertTrue(!storage.acceptedLicenses.isEmpty()); - } - - /** - * License can be accepted after reading its text. - */ - @Test - public void testSingleLicenseAcceptAfterRead() throws Exception { - addLoader("license.ruby"); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - - licF = new LicFeedback("INSTALL_AcceptLicense"); - delegateFeedback(licF); - licF.answer = "r"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - assertTrue(licF.questionAsked); - - // prepare - licF.questionAsked = false; - licF.licenseQuestion = "INSTALL_AcceptLicensePrompt"; - licF.answer = "y"; - pres.singleStep(); - - assertTrue(pres.isFinished()); - assertTrue(licenseIDs.isEmpty()); - assertFalse(storage.acceptedLicenses.isEmpty()); - } - - /** - * License can be accepted after reading its text. - */ - @Test - public void testSingleLicenseAAbortAfterRead() throws Exception { - addLoader("license.ruby"); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - - licF = new LicFeedback("INSTALL_AcceptLicense"); - delegateFeedback(licF); - licF.answer = "r"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - assertTrue(licF.questionAsked); - - // prepare - licF.questionAsked = false; - licF.licenseQuestion = "INSTALL_AcceptLicensePrompt"; - licF.answer = "X"; - exception.expect(UserAbortException.class); - pres.singleStep(); - } - - Map> savedLicenseIDs; - - public void assertYes() throws Exception { - licenseIDs.clear(); - licenseIDs.putAll(savedLicenseIDs); - pres.init(); - licF.answer = "Y"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - - licenseIDs.clear(); - licenseIDs.putAll(savedLicenseIDs); - pres.init(); - licF.answer = "yes"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - - licenseIDs.clear(); - licenseIDs.putAll(savedLicenseIDs); - pres.init(); - licF.answer = "YeS"; - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - } - - @Test - public void testMultiLicensesDisplaysMenu() throws Exception { - addLoader("license.python"); - addLoader("license.ruby"); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - licenseIDs.put(loader.getLicenseID(), new ArrayList<>(Arrays.asList(loader))); - pres.init(); - - assertFalse(pres.isFinished()); - assertEquals(LicensePresenter.State.LIST, pres.getState()); - - pres.singleStep(); - assertEquals(LicensePresenter.State.LISTINPUT, pres.getState()); - } - - @Test - public void testMultiAcceptAll() throws Exception { - addLoader("license.python"); - addLoader("license.ruby"); - - licF = new LicFeedback("INSTALL_AcceptAllLicensesPrompt"); - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - pres.singleStep(); - licF.answer = "Y"; - delegateFeedback(licF); - pres.singleStep(); - - assertTrue(pres.isFinished()); - assertEquals(2, storage.acceptedLicenses.size()); - } - - @Test - public void testMultiReadsLicense() throws Exception { - addLoader("license.python"); - addLoader("license.ruby"); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - - savedLicenseIDs = new LinkedHashMap<>(licenseIDs); - - class X extends LicFeedback { - StringBuilder licText = new StringBuilder(); - - X(String licenseQuestion) { - super(licenseQuestion); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - licText.append(msg); - return super.verbatimOut(msg, beVerbose); - } - } - X x = new X("INSTALL_AcceptAllLicensesPrompt"); - licF = x; - licF.answer = "1"; - delegateFeedback(licF); - pres.singleStep(); - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - - licF.answer = "y"; - pres.singleStep(); - assertTrue(x.licText.toString().toLowerCase().contains("python")); - - // single license remains, but still in LIST state - assertEquals(LicensePresenter.State.LIST, pres.getState()); - - // reinitialize - licenseIDs.clear(); - licenseIDs.putAll(savedLicenseIDs); - storage.acceptedLicenses.clear(); - x.licText.delete(0, x.licText.length()); - - pres.init(); - licF.answer = "2"; - pres.singleStep(); - pres.singleStep(); - assertEquals(LicensePresenter.State.LICENSE, pres.getState()); - - licF.answer = "y"; - pres.singleStep(); - assertTrue(x.licText.toString().toLowerCase().contains("ruby")); - - assertEquals(LicensePresenter.State.LIST, pres.getState()); - } - - @Rule public ProxyResource proxyResource = new ProxyResource(); - - /** - * Checks that a remote license is downloaded from the URL. - * - * @throws Exception - */ - @Test - public void testLicenseRemoteDownload() throws Exception { - addLoader("license.ruby"); - URL licURL = getClass().getResource("license.ruby/license.txt"); - - URL remoteUrl = SystemUtils.toURL("test://somewhere.org/license.txt"); - Handler.bind(remoteUrl.toString(), licURL); - licensedInfo.setLicensePath(remoteUrl.toString()); - - pres = new LicensePresenter(this, getLocalRegistry(), licenseIDs); - pres.init(); - - LicFeedback d = new LicFeedback("INSTALL_AcceptLicense"); - delegateFeedback(d); - d.answer = "y"; - pres.singleStep(); - assertTrue(pres.isFinished()); - - assertTrue(Handler.isVisited(remoteUrl)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ListTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ListTest.java deleted file mode 100644 index de1b18df4157..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/ListTest.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Path; -import java.util.HashSet; -import java.util.Locale; -import java.util.Objects; -import java.util.Properties; -import java.util.Set; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENTS; -import org.graalvm.component.installer.MemoryFeedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.remote.RemotePropertiesStorage; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONObject; -import org.graalvm.shadowed.org.json.JSONTokener; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; - -/** - * - * @author sdedic - */ -public class ListTest extends CommandTestBase { - @Rule public TestName name = new TestName(); - - private static final String GVM_VERSION = "1.0.0-rc3-dev"; - private static final String STABILITY = "ComponentStabilityLevel_undefined"; - - private RemotePropertiesStorage remoteStorage; - private Properties catalogContents = new Properties(); - - private void initRemoteStorage() throws MalformedURLException { - this.remoteStorage = new RemotePropertiesStorage( - this, getLocalRegistry(), catalogContents, - "linux_amd64", - Version.fromString("1.0.0-rc3-dev"), - SystemUtils.toURL("http://go.to/graalvm")); - this.registry = new CatalogContents(this, remoteStorage, localRegistry); - } - - private StringBuilder outb = new StringBuilder(); - - @Test - public void testAvailablePrintAll() throws Exception { - try (InputStream is = getClass().getResourceAsStream("catalog.rcb1")) { - catalogContents.load(is); - } - initRemoteStorage(); - - options.put(Commands.OPTION_SHOW_UPDATES, ""); - AvailableCommand avC = new AvailableCommand(); - avC.init(this, this.withBundle(AvailableCommand.class)); - - delegateFeedback(new FeedbackAdapter() { - @Override - public String l10n(String key, Object... params) { - if ("LIST_ComponentShortList".equals(key) || (key != null && key.startsWith("ComponentStability"))) { - return reallyl10n(key, params); - } - return null; - } - - @Override - public void output(String bundleKey, Object... params) { - outb.append(bundleKey); - if (params != null && params.length > 0) { - outb.append("{"); - for (Object o : params) { - outb.append(Objects.toString(o)); - } - outb.append("}"); - } - outb.append("\n"); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - outb.append(msg).append("\n"); - return super.verbatimOut(msg, beVerbose); - } - }); - avC.execute(); - - assertOutputContents(null); - } - - private void assertOutputContents(String aMsg) throws Exception { - String msg = aMsg != null ? aMsg : "Contents must match"; - String n = name.getMethodName(); - if (n.startsWith("test") && n.length() > 6) { - n = Character.toLowerCase(n.charAt(4)) + n.substring(5); - } - URL u = getClass().getResource(n + ".golden"); - if (u == null) { - return; - } - StringBuilder check = new StringBuilder(); - try (InputStream is = u.openStream(); - BufferedReader rdr = new BufferedReader(new InputStreamReader(is))) { - String s = null; - - while ((s = rdr.readLine()) != null) { - if (check.length() > 0) { - check.append("\n"); - } - check.append(s); - } - } - assertEquals(msg, check.toString(), outb.toString()); - } - - /** - * Tests that 'list' will print matching components. - */ - @Test - public void testListSpecifiedComponents() throws Exception { - storage.installed.add( - new ComponentInfo("org.graalvm.R", "FastR", Version.fromString("1.0.0"))); - storage.installed.add( - new ComponentInfo("org.graalvm.ruby", "Ruby", Version.fromString("1.0.0"))); - storage.installed.add( - new ComponentInfo("org.graalvm.python", "Python", Version.fromString("1.0.0"))); - - ListInstalledCommand inst = new ListInstalledCommand() { - @Override - boolean process() { - super.process(); - // block the actual print - return false; - } - }; - textParams.add("ruby"); - textParams.add("r"); - textParams.add("python"); - inst.init(this, this); - - inst.execute(); - - Set found = new HashSet<>(); - assertEquals(3, inst.getComponents().size()); - for (ComponentInfo ci : inst.getComponents()) { - assertTrue(found.add(ci.getId().toLowerCase())); - } - assertTrue(found.contains("org.graalvm.r")); - assertTrue(found.contains("org.graalvm.ruby")); - assertTrue(found.contains("org.graalvm.python")); - } - - /** - * Tests that 'list' will print components but just those newer than us. - */ - @Test - public void testListSpecifiedNewerComponents() throws Exception { - Version v = Version.fromString("1.1.0"); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, v.originalString()); - assert110Components(v, v); - } - - /** - * Checks that compatible components will be listed if 1st parameter is the version. - */ - @Test - public void testListSpecifiedNewerComponentsExplicit() throws Exception { - Version v = Version.fromString("1.0.0"); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, v.originalString()); - textParams.add("+1.1.0"); - assert110Components(v, Version.fromString("1.1.0")); - } - - private void assert110Components(Version v, Version min) throws Exception { - Path p = dataFile("../repo/catalog.properties"); - try (InputStream is = new FileInputStream(p.toFile())) { - catalogContents.load(is); - } - this.remoteStorage = new RemotePropertiesStorage( - this, getLocalRegistry(), catalogContents, - "linux_amd64", - v, - SystemUtils.toURL("http://go.to/graalvm")); - this.registry = new CatalogContents(this, remoteStorage, localRegistry); - - AvailableCommand inst = new AvailableCommand() { - @Override - boolean process() { - super.process(); - // block the actual print - return false; - } - }; - textParams.add("r"); - textParams.add("ruby"); - textParams.add("python"); - inst.init(this, this.withBundle(ListInstalledCommand.class)); - - inst.execute(); - - Set found = new HashSet<>(); - for (ComponentInfo ci : inst.getComponents()) { - if (ci.getId().equals(BundleConstants.GRAAL_COMPONENT_ID)) { - continue; - } - assertTrue(found.add(ci.getId().toLowerCase())); - assertTrue(min.compareTo(ci.getVersion()) <= 0); - } - // ruby not present - assertFalse(found.contains("org.graalvm.ruby")); - assertTrue(found.contains("org.graalvm.r")); - assertTrue(found.contains("org.graalvm.python")); - } - - @Test - public void testJSONOutput() throws Exception { - options.put(Commands.OPTION_JSON_OUTPUT, ""); - - try (InputStream is = getClass().getResourceAsStream("catalog.rcb1")) { - catalogContents.load(is); - } - initRemoteStorage(); - - options.put(Commands.OPTION_SHOW_UPDATES, ""); - AvailableCommand avC = new AvailableCommand(); - avC.init(this, this.withBundle(AvailableCommand.class)); - - MemoryFeedback mf = new MemoryFeedback(); - delegateFeedback(mf); - avC.execute(); - - for (MemoryFeedback.Memory mem : mf) { - if (!mem.silent) { - JSONObject jo = new JSONObject(new JSONTokener(mem.key)); - JSONArray comps = jo.getJSONArray(JSON_KEY_COMPONENTS); - assertEquals(3, comps.length()); - for (int i = 0; i < comps.length(); ++i) { - JSONObject comp = comps.getJSONObject(i); - assertEquals(comp.toString(2), GVM_VERSION, comp.getString(CommonConstants.JSON_KEY_COMPONENT_GRAALVM)); - assertEquals(comp.toString(2), GVM_VERSION, comp.getString(CommonConstants.JSON_KEY_COMPONENT_VERSION)); - assertEquals(comp.toString(2), STABILITY, comp.getString(CommonConstants.JSON_KEY_COMPONENT_STABILITY)); - assertTrue(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_ORIGIN).contains(comp.getString(CommonConstants.JSON_KEY_COMPONENT_ID).toLowerCase(Locale.ENGLISH))); - assertTrue(comp.toString(2), comp.getString(CommonConstants.JSON_KEY_COMPONENT_NAME) != null); - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/MockStorage.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/MockStorage.java deleted file mode 100644 index 8067212efd4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/MockStorage.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import static org.graalvm.component.installer.CommonConstants.CAP_GRAALVM_VERSION; -import static org.graalvm.component.installer.CommonConstants.CAP_OS_ARCH; -import static org.graalvm.component.installer.CommonConstants.CAP_OS_NAME; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.CAP_JAVA_VERSION; -import org.graalvm.component.installer.FailedOperationException; - -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ManagementStorage; - -/** - * Mock implementation of component storage to avoid mess with disk files. - */ -public class MockStorage implements ManagementStorage { - public static final Map DEFAULT_GRAAL_INFO = new HashMap<>(); - - static { - DEFAULT_GRAAL_INFO.put(CAP_GRAALVM_VERSION, "0.32"); - DEFAULT_GRAAL_INFO.put(CAP_OS_ARCH, "amd64"); - DEFAULT_GRAAL_INFO.put(CAP_OS_NAME, "linux"); - DEFAULT_GRAAL_INFO.put(CAP_JAVA_VERSION, "8"); - DEFAULT_GRAAL_INFO.put(CommonConstants.CAP_EDITION, "ce"); - } - - public Map> acceptedLicenses = new HashMap<>(); - public Map licText = new HashMap<>(); - public List installed = new ArrayList<>(); - public Map graalInfo = new HashMap<>(DEFAULT_GRAAL_INFO); - public Map> replacedFiles = new HashMap<>(); - public Map> updatedReplacedFiles = new HashMap<>(); - public List savedInfos = new ArrayList<>(); - public String writableUser; - - @Override - public void deleteComponent(String id) throws IOException { - // no op - for (Iterator it = installed.iterator(); it.hasNext();) { - ComponentInfo info = it.next(); - if (id.equals(info.getId())) { - it.remove(); - } - } - } - - @Override - public Set listComponentIDs() throws IOException { - return installed.stream().map((ci) -> ci.getId()).collect(Collectors.toSet()); - } - - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - return ci; - } - - @Override - public Set loadComponentMetadata(String tag) throws IOException { - ComponentInfo ret = installed.stream().filter((ci) -> ci.getId().equals(tag)).findFirst().orElse(null); - return ret == null ? null : Collections.singleton(ret); - } - - @Override - public Map loadGraalVersionInfo() { - return graalInfo; - } - - @Override - public Map> readReplacedFiles() throws IOException { - return new HashMap<>(replacedFiles); - } - - @Override - public void saveComponent(ComponentInfo info) throws IOException { - // simulate DiretoryStorage verification - if (writableUser != null) { - throw new FailedOperationException("ADMIN"); - } - savedInfos.add(info); - } - - @Override - public void updateReplacedFiles(Map> newReplacedFiles) throws IOException { - updatedReplacedFiles = newReplacedFiles; - } - - @Override - public Date licenseAccepted(ComponentInfo info, String licenseID) { - return acceptedLicenses.getOrDefault(info.getId(), Collections.emptyMap()).get(licenseID); - } - - @Override - public void recordLicenseAccepted(ComponentInfo info, String licenseID, String text, Date d) throws IOException { - if (info == null) { - acceptedLicenses.clear(); - return; - } - Map acc = acceptedLicenses.computeIfAbsent(info.getId(), (i) -> new HashMap<>()); - if (licenseID != null) { - acc.put(licenseID, d != null ? d : new Date()); - licText.putIfAbsent(licenseID, text); - } else { - acc.clear(); - } - } - - @Override - public Map> findAcceptedLicenses() { - Map> result = new HashMap<>(); - for (String id : acceptedLicenses.keySet()) { - result.put(id, acceptedLicenses.get(id).keySet()); - } - return result; - } - - @Override - public String licenseText(String licID) { - return licText.get(licID); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UninstallTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UninstallTest.java deleted file mode 100644 index dcca24427908..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UninstallTest.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.nio.file.Path; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; - -/** - * - * @author sdedic - */ -public class UninstallTest extends CommandTestBase { - @Rule public TestName name = new TestName(); - @Rule public ExpectedException exception = ExpectedException.none(); - - CatalogContents componentCatalog; - - private void setupComponentsWithDeps() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "19.3-dev"); - Path catalogFile = dataFile("cataloginstallDeps.properties"); - RemoteCatalogDownloader downloader = new RemoteCatalogDownloader(this, this, - catalogFile.toUri().toURL()); - componentCatalog = new CatalogContents(this, downloader.getStorage(), getLocalRegistry()); - - ComponentInfo ruby = componentCatalog.findComponent("org.graalvm.ruby"); - ComponentInfo fastr = componentCatalog.findComponent("org.graalvm.r"); - Set deps = new HashSet<>(); - componentCatalog.findDependencies(ruby, true, null, deps); - componentCatalog.findDependencies(fastr, true, null, deps); - deps.add(ruby); - deps.add(fastr); - storage.installed.addAll(deps); - deps.forEach((ci) -> ci.setInfoPath("")); - } - - /** - * Schedules uninstallation of a leaf component, no breakages. - */ - @Test - public void testUninstallLeaf() throws Exception { - setupComponentsWithDeps(); - - UninstallCommand uc = new UninstallCommand(); - uc.init(this, this); - textParams.add("ruby"); - uc.prepareUninstall(); - assertTrue(uc.getBrokenDependencies().isEmpty()); - assertEquals(1, uc.getUninstallComponents().size()); - - // should succeed - uc.checkBrokenDependencies(); - } - - /** - * Schedules uninstallation of a library. One component should become broken. - */ - @Test - public void testUninstallLibraryFailure() throws Exception { - setupComponentsWithDeps(); - - UninstallCommand uc = new UninstallCommand(); - uc.init(this, this.withBundle(UninstallCommand.class)); - textParams.add("org.graalvm.native-image"); - - uc.prepareUninstall(); - assertFalse(uc.getBrokenDependencies().isEmpty()); - assertEquals(1, uc.getUninstallComponents().size()); - - ComponentInfo nimage = localRegistry.findComponent("org.graalvm.native-image"); - ComponentInfo ruby = localRegistry.findComponent("org.graalvm.ruby"); - assertSame(nimage, uc.getUninstallComponents().iterator().next()); - - Collection broken = uc.getBrokenDependencies().get(nimage); - assertNotNull(broken); - assertSame(ruby, broken.iterator().next()); - - exception.expect(FailedOperationException.class); - exception.expectMessage("UNINSTALL_BreakDependenciesTerminate"); - uc.checkBrokenDependencies(); - } - - @Test - public void testUninstallIgnoreDeps() throws Exception { - setupComponentsWithDeps(); - options.put(Commands.OPTION_NO_DEPENDENCIES, ""); - - UninstallCommand uc = new UninstallCommand(); - uc.init(this, this.withBundle(UninstallCommand.class)); - textParams.add("org.graalvm.native-image"); - - uc.prepareUninstall(); - assertTrue(uc.getBrokenDependencies().isEmpty()); - - uc.checkBrokenDependencies(); - uc.includeAndOrderComponents(); - List comps = uc.getUninstallSequence(); - assertEquals(1, comps.size()); - } - - /** - * Library is to be uninstalled together with a feature it is using the library. Should succeed - */ - @Test - public void testUninstallLibraryWithUsers() throws Exception { - setupComponentsWithDeps(); - - UninstallCommand uc = new UninstallCommand(); - uc.init(this, this.withBundle(UninstallCommand.class)); - textParams.add("org.graalvm.native-image"); - textParams.add("org.graalvm.ruby"); - - uc.prepareUninstall(); - // broken ruby is recorded - assertFalse(uc.getBrokenDependencies().isEmpty()); - assertEquals(2, uc.getUninstallComponents().size()); - // however it will not fail the installation - uc.checkBrokenDependencies(); - } - - /** - * Force flag allows to broken components. Check that warning is printed. - */ - @Test - public void testUninstallBreakForced() throws Exception { - setupComponentsWithDeps(); - - UninstallCommand uc = new UninstallCommand(); - uc.init(this, this.withBundle(UninstallCommand.class)); - uc.setBreakDependent(true); - textParams.add("org.graalvm.native-image"); - - uc.prepareUninstall(); - // broken ruby is recorded - assertFalse(uc.getBrokenDependencies().isEmpty()); - assertEquals(1, uc.getUninstallComponents().size()); - class FD extends FeedbackAdapter { - boolean target; - - @Override - public void error(String key, Throwable t, Object... params) { - fail("No error should be printed"); - } - - @Override - public void output(String bundleKey, Object... params) { - switch (bundleKey) { - case "UNINSTALL_BreakDepSource": - assertEquals("org.graalvm.native-image", params[1]); - break; - - case "UNINSTALL_BreakDepTarget": - target = true; - assertEquals("org.graalvm.ruby", params[1]); - break; - } - } - - } - FD fd = new FD(); - delegateFeedback(fd); - uc.checkBrokenDependencies(); - assertTrue(fd.target); - } - - /** - * Checks that uninstallation of a library with a flag will imply uninstallation of dependents. - * Verifies the order of uninstallation. - */ - @Test - public void testUninstallLibraryImplyDependents() throws Exception { - setupComponentsWithDeps(); - - UninstallCommand uc = new UninstallCommand(); - uc.init(this, this.withBundle(UninstallCommand.class)); - uc.setRemoveDependent(true); - textParams.add("org.graalvm.llvm-toolchain"); - - uc.prepareUninstall(); - // broken ruby is recorded - assertFalse(uc.getBrokenDependencies().isEmpty()); - assertEquals(1, uc.getUninstallComponents().size()); - // however it will not fail the installation - uc.checkBrokenDependencies(); - - uc.includeAndOrderComponents(); - - List comps = uc.getUninstallSequence(); - assertEquals(4, comps.size()); - - // handle possible different ordering of the component removal - int nativeIndex = comps.indexOf(localRegistry.findComponent("org.graalvm.native-image")); - int rubyIndex = comps.indexOf(localRegistry.findComponent("org.graalvm.ruby")); - int rIndex = comps.indexOf(localRegistry.findComponent("org.graalvm.r")); - - // native depends on llvm so llvm must be the last; native may not be the first, as ruby - // depends on it - assertTrue(nativeIndex > 0 && nativeIndex < 3); - assertTrue(rubyIndex < nativeIndex); - assertTrue(rIndex < 3); - assertEquals("org.graalvm.llvm-toolchain", comps.get(3).getId()); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UpgradeTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UpgradeTest.java deleted file mode 100644 index e2a0b5520583..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/UpgradeTest.java +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.UnknownVersionException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.GraalEdition; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class UpgradeTest extends CommandTestBase { - private UpgradeProcess helper; - private RemoteCatalogDownloader downloader; - - private Version initVersion(String s) throws IOException { - return initVersion(s, "../repo/catalog.properties"); - } - - private Version initVersion(String s, String catalogResource) throws IOException { - Version v = Version.fromString(s); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, s); - Path catalogPath = dataFile(catalogResource); - downloader = new RemoteCatalogDownloader( - this, - this, - catalogPath.toUri().toURL()); - - registry = new CatalogContents(this, downloader.getStorage(), localRegistry); - paramIterable = new CatalogIterable(this, this); - helper = new UpgradeProcess(this, this, registry); - return v; - } - - /** - * Checks situation when no upgrade is available. - */ - @Test - public void testNoUpgrade() throws Exception { - initVersion("1.1.1-0.rc.1"); - ComponentInfo info = helper.findGraalVersion(localRegistry.getGraalVersion().match(Version.Match.Type.INSTALLABLE)); - assertNotNull(info); - assertEquals(localRegistry.getGraalVersion(), info.getVersion()); - assertFalse(helper.prepareInstall(info)); - } - - /** - * Tests "gu upgrade" commandline on a most recent version. - */ - @Test - public void testNoUpgradeCommand() throws Exception { - initVersion("1.1.1-0.rc.1"); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - // no upgrade performed. - assertEquals(1, cmd.execute()); - - assertFalse(Files.list(getGraalHomePath().getParent()).anyMatch((fn) -> fn.getFileName().toString().contains("rc.1"))); - } - - @Test - public void testRefuseDowngradeComponentsFail() throws Exception { - initVersion("1.1.0.1"); - ComponentInfo info = helper.findGraalVersion( - Version.fromString("1.0.0.0").match(Version.Match.Type.EXACT)); - assertNull(info); - } - - @Test - public void testRefuseDowngradeFromCommandline() throws Exception { - exception.expect(FailedOperationException.class); - exception.expectMessage("UPGRADE_CannotDowngrade"); - - initVersion("1.1.0.1"); - textParams.add("1.0.0.0"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - cmd.execute(); - } - - @Test - public void testUpgradeToCompatibleVersion() throws Exception { - initVersion("1.0.0.0"); - textParams.add("1.0.1"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - helper.resetExistingComponents(); - ComponentInfo info = helper.findGraalVersion( - Version.fromString("1.0.1").match(Version.Match.Type.COMPATIBLE)); - assertNotNull(info); - assertEquals("1.0.1.0", info.getVersion().toString()); - } - - /** - * Tests "gu upgrade 1.0.1" on 1.0.1 installation. 1.0.1 core should be installed with ruby - * 1.0.1.1 - */ - @Test - public void testUpgradeToCompatibleVersionCommandline() throws Exception { - initVersion("1.0.0.0"); - textParams.add("1.0.1"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - assertEquals(0, cmd.execute()); - - ComponentRegistry newReg = cmd.getProcess().getNewGraalRegistry(); - ComponentInfo ruby = newReg.findComponent("ruby"); - assertEquals("1.0.1.1", ruby.getVersion().toString()); - } - - @Test - public void testRefuseUpgradeUnsatisfiedComponent() throws Exception { - exception.expect(FailedOperationException.class); - exception.expectMessage("UPGRADE_ComponentsCannotMigrate"); - - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - helper.resetExistingComponents(); - ComponentInfo info = helper.findGraalVersion( - Version.fromString("1.1.0").match(Version.Match.Type.COMPATIBLE)); - assertNotNull(info); - } - - /** - * Checks "gu upgrade 1.1.0". Should fail because ruby is not available in 1.1.x - */ - @Test - public void testRefuseUnsatisfiedCommandline() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - textParams.add("1.1.0"); - storage.installed.add(ci); - - exception.expect(FailedOperationException.class); - exception.expectMessage("UPGRADE_ComponentsCannotMigrate"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - cmd.execute(); - } - - /** - * Checks "gu upgrade". Should select 1.0.1.0 with ruby 1.0.1.1 since in newer Graals Ruby is - * not available - */ - @Test - public void testUpgradeToNewestAvailable() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - cmd.execute(); - - Version installedGraalVMVersion = cmd.getProcess().getNewGraalRegistry().getGraalVersion(); - Version installedRubyVersion = cmd.getProcess().getNewGraalRegistry().findComponent("ruby").getVersion(); - - assertEquals("1.0.1.0", installedGraalVMVersion.toString()); - assertEquals("1.0.1.1", installedRubyVersion.toString()); - } - - /** - * Ignores unsatisfied component dependency and install the most recent GraalVM version. - */ - @Test - public void testIgnoreUnsatisfiedComponent() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - helper.resetExistingComponents(); - helper.setAllowMissing(true); - ComponentInfo info = helper.findGraalVersion( - Version.fromString("1.1.0").match(Version.Match.Type.COMPATIBLE)); - assertNotNull(info); - assertEquals("1.1.0.1", info.getVersion().toString()); - } - - /** - * Checks "gu upgrade". Should select 1.0.1.0 with ruby 1.0.1.1 since in newer Graals Ruby is - * not available - */ - @Test - public void testIgnoreUnsatisfiedComponentCommandline() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - options.put(Commands.OPTION_IGNORE_MISSING_COMPONENTS, ""); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - cmd.execute(); - - Version installedGraalVMVersion = cmd.getProcess().getNewGraalRegistry().getGraalVersion(); - assertEquals("1.1.1-0.rc.1", installedGraalVMVersion.originalString()); - assertNull("Ruby should not be migrated", cmd.getProcess().getNewGraalRegistry().findComponent("ruby")); - } - - /** - * Checks installation without core , even though the user has specified the version. Simulates - * "gu install ruby" on 1.0.1.0 installation which ought to install 1.0.1.1 - */ - @Test - public void testInstallWithoutCoreUpgrade() throws Exception { - initVersion("1.0.1.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.1.0"); - storage.installed.add(ci); - helper.resetExistingComponents(); - - ComponentInfo info = helper.findGraalVersion( - Version.fromString("1.0.1").match(Version.Match.Type.COMPATIBLE)); - assertNotNull(info); - boolean inst = helper.installGraalCore(info); - assertFalse(inst); - } - - /** - * Upgrade command is used to install a new component, but the core is most recent one and need - * not to be upgraded. Component must go to the existing install. - * - * @throws Exception - */ - @Test - public void testInstallNewWithoutCoreUpgrade() throws Exception { - initVersion("1.0.1.0"); - textParams.add("ruby"); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - helper = cmd.getProcess(); - - ComponentInfo info = cmd.configureProcess(); - assertNotNull(info); - // will not install core - assertFalse(helper.installGraalCore(info)); - assertNull(helper.getTargetInfo()); - - // found the current graalvm: - assertEquals(getLocalRegistry().getGraalVersion(), info.getVersion()); - List toDownload = helper.allComponents(); - - // no component (e.g. migration) was added, requested ruby is in there - assertEquals(1, toDownload.size()); - assertEquals("org.graalvm.ruby", toDownload.get(0).getShortName()); - } - - /** - * Checks that "gu update r" will only update to a minor update, not to the next major. - * - * @throws Exception - */ - @Test - public void testInstallMinorUpdate() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - - UpgradeCommand cmd = new UpgradeCommand(false); - cmd.init(this, this); - ComponentInfo info = cmd.configureProcess(); - assertFalse(cmd.getProcess().prepareInstall(info)); - } - - @Test - public void testRefuseNonAdminUpgrade() throws Exception { - initVersion("1.0.0.0"); - storage.writableUser = "hero"; // NOI18N - - textParams.add("1.0.1"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - - exception.expect(FailedOperationException.class); - exception.expectMessage("ADMIN"); - - cmd.execute(); - } - - /** - * Checks that the 'components can migrate' check succeed, if an existing component is specified - * for upgrade. - */ - @Test - public void testUpgradeExistingComponent() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - textParams.add("ruby"); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - helper = cmd.getProcess(); - - ComponentInfo info = cmd.configureProcess(); - assertNotNull(info); - assertEquals(Version.fromString("1.0.1"), info.getVersion()); - } - - /** - * Fails on non-empty directory. - */ - @Test - public void testInstallIntoExistingNonempty() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - textParams.add("ruby"); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - helper = cmd.getProcess(); - - ComponentInfo info = cmd.configureProcess(); - Path p = getGraalHomePath().normalize(); - Path ndir = graalVMDirectory(p, "1.0.1"); - Files.createDirectories(ndir); - Files.write(ndir.resolve("some-content"), Arrays.asList("Fail")); - - exception.expect(FailedOperationException.class); - exception.expectMessage("UPGRADE_TargetExistsNotEmpty"); - helper.prepareInstall(info); - } - - private Path graalVMDirectory(Path sibling, String version) { - return sibling.resolveSibling("graalvm-ce-java" + - getLocalRegistry().getGraalCapabilities().get(CommonConstants.CAP_JAVA_VERSION) + "-" + version); - } - - /** - * Fails on non-empty directory. - */ - @Test - public void testInstallIntoExistingRelease() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - textParams.add("ruby"); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - helper = cmd.getProcess(); - - ComponentInfo info = cmd.configureProcess(); - Path p = getGraalHomePath().normalize(); - Path ndir = graalVMDirectory(p, "1.0.1"); - Files.createDirectories(ndir); - Files.write(ndir.resolve("some-content"), Arrays.asList("Fail")); - Path toCopy = dataFile("../persist/release_simple.properties"); - Files.copy(toCopy, ndir.resolve("release")); - - exception.expect(FailedOperationException.class); - exception.expectMessage("UPGRADE_TargetExistsContainsGraalVM"); - helper.prepareInstall(info); - } - - /** - * Allows to install to an empty location. - */ - @Test - public void testInstallIntoExistingEmpty() throws Exception { - initVersion("1.0.0.0"); - ComponentInfo ci = new ComponentInfo("org.graalvm.ruby", "Installed Ruby", "1.0.0.0"); - storage.installed.add(ci); - textParams.add("ruby"); - - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - helper = cmd.getProcess(); - - ComponentInfo info = cmd.configureProcess(); - Path p = getGraalHomePath().normalize(); - Path ndir = graalVMDirectory(p, "1.0.1"); - Files.createDirectories(ndir); - - assertTrue(helper.prepareInstall(info)); - } - - /** - * Tests upgrade to version AT LEAST 1.0.1. - */ - @Test - public void testUpgradePythonMostRecent() throws Exception { - initVersion("1.0.0.0"); - textParams.add("python+1.0.1"); - ComponentInfo ci = new ComponentInfo("org.graalvm.python", "Installed Python", "1.0.0.0"); - storage.installed.add(ci); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - assertEquals(0, cmd.execute()); - - ComponentRegistry newReg = cmd.getProcess().getNewGraalRegistry(); - ComponentInfo python = newReg.findComponent("python"); - assertEquals("1.1.0.0", python.getVersion().toString()); - } - - /** - * Tests upgrade to version EXACTLY 1.0.1. - */ - @Test - public void testUpgradeExact() throws Exception { - initVersion("1.0.0.0"); - textParams.add("python=1.0.1"); - ComponentInfo ci = new ComponentInfo("org.graalvm.python", "Installed Python", "1.0.0.0"); - storage.installed.add(ci); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - assertEquals(0, cmd.execute()); - - ComponentRegistry newReg = cmd.getProcess().getNewGraalRegistry(); - ComponentInfo python = newReg.findComponent("python"); - // note the difference, the user string does not contain trailing .0 - assertEquals("1.0.1", python.getVersion().displayString()); - } - - /** - * Tests upgrade to a next version's RC. - */ - @Test - public void testUpgradeToNextRC() throws Exception { - initVersion("1.0.0.0"); - textParams.add("1.1.1-rc"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - assertEquals(0, cmd.execute()); - - ComponentRegistry newReg = cmd.getProcess().getNewGraalRegistry(); - assertEquals("1.1.1.0-0.rc.1", newReg.getGraalVersion().toString()); - } - - /** - * Tests NO upgrade to RC when requesting a release. - */ - @Test - public void testNoUpgradeToRCInsteadOfRelease() throws Exception { - initVersion("1.0.0.0"); - textParams.add("1.1.1"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - try { - cmd.execute(); - } catch (UnknownVersionException ex) { - assertNotNull(ex.getCandidate()); - assertTrue(ex.getCandidate().toString().contains("rc")); - } - } - - /** - * Tests NO upgrade to RC when requesting a release. - */ - @Test - public void testUpgradeIfAllowsNewer() throws Exception { - initVersion("1.0.0.0"); - textParams.add("+1.1.1"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - assertEquals(0, cmd.execute()); - ComponentRegistry newReg = cmd.getProcess().getNewGraalRegistry(); - assertEquals("1.1.1.0-0.rc.1", newReg.getGraalVersion().toString()); - } - - /** - * Checks that upgrade will install graal of the specified version. - */ - @Test - public void testUpgradeFromDevToSpecificVersion() throws Exception { - initVersion("1.0.0-dev"); - textParams.add("1.0.1"); - textParams.add("python"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - ComponentInfo graalInfo = cmd.configureProcess(); - assertNotNull(graalInfo); - // check that GraalVM appropriate for 1.0.1 component is selected - assertEquals("1.0.1.0", graalInfo.getVersion().toString()); - assertEquals(1, cmd.getProcess().addedComponents().size()); - ComponentParam p = cmd.getProcess().addedComponents().iterator().next(); - ComponentInfo ci = p.createMetaLoader().getComponentInfo(); - // check that component 1.0.1 will be installed - assertEquals("1.0.1.0", ci.getVersion().toString()); - } - - /** - * Checks that upgrade will install graal for the specific Component. - */ - @Test - public void testUpgradeFromDevToSpecificVersion2() throws Exception { - initVersion("1.0.0-dev"); - textParams.add("python=1.0.1"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - ComponentInfo graalInfo = cmd.configureProcess(); - assertNotNull(graalInfo); - // check that GraalVM appropriate for 1.0.1 component is selected - assertEquals("1.0.1.0", graalInfo.getVersion().toString()); - assertEquals(1, cmd.getProcess().addedComponents().size()); - ComponentParam p = cmd.getProcess().addedComponents().iterator().next(); - ComponentInfo ci = p.createMetaLoader().getComponentInfo(); - // check that component 1.0.1 will be installed - assertEquals("1.0.1.0", ci.getVersion().toString()); - } - - /** - * Checks that upgrade will install graal for the specific Component. - */ - @Test - public void testUpgradeToSameVersion() throws Exception { - initVersion("1.0.0-dev"); - textParams.add("1.0.0-dev"); - textParams.add("python"); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - ComponentInfo graalInfo = cmd.configureProcess(); - assertNotNull(graalInfo); - // check that GraalVM appropriate for 1.0.1 component is selected - assertEquals("1.0.0-dev", graalInfo.getVersion().displayString()); - assertEquals(1, cmd.getProcess().addedComponents().size()); - ComponentParam p = cmd.getProcess().addedComponents().iterator().next(); - ComponentInfo ci = p.createMetaLoader().getComponentInfo(); - // check that component 1.0.1 will be installed - assertEquals("1.0.0-dev", ci.getVersion().displayString()); - } - - static class InstallTrampoline extends InstallCommand { - - @Override - protected void prepareInstallation() throws IOException { - super.prepareInstallation(); - } - - @Override - protected void executionInit() throws IOException { - super.executionInit(); - } - - } - - CatalogFactory factory; - - @Override - public CatalogFactory getCatalogFactory() { - return factory != null ? factory : super.getCatalogFactory(); - } - - /** - * Upgrade an installation with "ruby" to a newer one, where "ruby" has a dependency on an - * additional component. The other component should be auto-installed. - */ - @Test - public void testUpgradeWithDependencies() throws Exception { - initVersion("1.0.0.0", "../repo/catalog-19.3.properties"); - - ComponentInfo ci = new ComponentInfo("org.graalvm.r", "Installed R", "1.0.0.0"); - storage.installed.add(ci); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - - textParams.add("r"); - ComponentInfo graalInfo = cmd.configureProcess(); - assertNotNull(graalInfo); - assertEquals(Version.fromString("19.3.0.0"), graalInfo.getVersion()); - - boolean installed = cmd.getProcess().installGraalCore(graalInfo); - assertTrue(installed); - - factory = new CatalogFactory() { - @Override - public ComponentCatalog createComponentCatalog(CommandInput in) { - RemoteCatalogDownloader dnl = new RemoteCatalogDownloader(in, UpgradeTest.this, downloader.getOverrideCatalogSpec()); - // carry over the override spec - return new CatalogContents(UpgradeTest.this, dnl.getStorage(), in.getLocalRegistry()); - } - - @Override - public List listEditions(ComponentRegistry targetGraalVM) { - return Collections.emptyList(); - } - }; - - InstallTrampoline targetInstall = new InstallTrampoline(); - cmd.getProcess().configureInstallCommand(targetInstall); - targetInstall.executionInit(); - targetInstall.prepareInstallation(); - - assertTrue(targetInstall.getUnresolvedDependencies().isEmpty()); - List deps = targetInstall.getDependencies(); - assertEquals(1, deps.size()); - MetadataLoader ldr = deps.iterator().next().createFileLoader(); - assertEquals("org.graalvm.llvm-toolchain", ldr.getComponentInfo().getId()); - } - - @Rule public ProxyResource proxyResource = new ProxyResource(); - - @After - public void clearHandlerBindings() { - Handler.clear(); - } - - /** - * The target GraalVM installation may have configured the catalog URLs differently. When - * installing components or dependencies to the target, the target's URLs / release file - * settings should be respected. - * - * @throws Exception - */ - @Test - public void testUpgradeRespectsTargetCatalogURLs() throws Exception { - URL u = SystemUtils.toURL("test://catalog-19.3.properties"); - Handler.bind(u.toString(), dataFile("../repo/catalog-19.3.properties").toUri().toURL()); - - initVersion("1.0.0.0", "../repo/catalog-19.3.properties"); - - ComponentInfo ci = new ComponentInfo("org.graalvm.r", "Installed R", "1.0.0.0"); - storage.installed.add(ci); - UpgradeCommand cmd = new UpgradeCommand(); - cmd.init(this, this); - ComponentInfo graalInfo = cmd.configureProcess(); - boolean installed = cmd.getProcess().installGraalCore(graalInfo); - assertTrue(installed); - factory = new CatalogFactory() { - @Override - public ComponentCatalog createComponentCatalog(CommandInput in) { - RemoteCatalogDownloader dnl = new RemoteCatalogDownloader(in, UpgradeTest.this, (String) null); - return new CatalogContents(UpgradeTest.this, dnl.getStorage(), in.getLocalRegistry()); - } - - @Override - public List listEditions(ComponentRegistry targetGraalVM) { - return Collections.emptyList(); - } - }; - InstallTrampoline targetInstall = new InstallTrampoline(); - cmd.getProcess().configureInstallCommand(targetInstall); - targetInstall.executionInit(); - targetInstall.prepareInstallation(); - - // verify the URL from the target installation was visited. - assertTrue(Handler.isVisited(u)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/availablePrintAll.golden b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/availablePrintAll.golden deleted file mode 100644 index 98645649fe0c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/availablePrintAll.golden +++ /dev/null @@ -1,8 +0,0 @@ -LIST_ComponentShortListHeader -python 1.0.0-rc3-dev Graal.Python - acme.org -python 1.0.0-rc3-dev Graal.Python - acme.org -R 1.0.0-rc3-dev FastR - acme.org -R 1.0.0-rc3-dev FastR - acme.org -ruby 1.0.0-rc3-dev TruffleRuby - acme.org -ruby 1.0.0-rc3-dev TruffleRuby - acme.org - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog deleted file mode 100644 index 73750be71f5c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog +++ /dev/null @@ -1,12 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog.rcb1 b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog.rcb1 deleted file mode 100644 index 00bea9a17e90..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalog.rcb1 +++ /dev/null @@ -1,45 +0,0 @@ -org.graalvm.1.0.0-rc3-dev_darwin_amd64=GraalVM 1.0.0-rc3-dev darwin/amd64 -org.graalvm.1.0.0-rc3-dev_linux_amd64=GraalVM 1.0.0-rc3-dev linux/amd64 - -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby=http://acme.org/graal/components/darwin-amd64/ce/ruby-installable.jar -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby-hash=dd03c98b2080112ceea281f42783512db86f3ef5a940679c6c60514c87de8dd6 -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc3-dev)(os_name=darwin)(os_arch=amd64))" -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby-Bundle-Version=1.0.0-rc3-dev -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r=http://acme.org/graal/components/darwin-amd64/ce/r-installable.jar -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r-hash=13f37bd01e7f8f40c9f64dc15f027c53863f8c4cd319564855a25b3bdd1c0b9a -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc3-dev)(os_name=darwin)(os_arch=amd64))" -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r-Bundle-Version=1.0.0-rc3-dev -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python=http://acme.org/graal/components/darwin-amd64/ce/python-installable.jar -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python-hash=278bff9dbfcd73bc0cc2cddf81545feed9bae4e5ead00d3763dfe003da7e4f66 -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc3-dev)(os_name=darwin)(os_arch=amd64))" -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python-Bundle-Version=1.0.0-rc3-dev -Component.1.0.0-rc3-dev_darwin_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby=http://acme.org/graal/components/linux-amd64/ce/ruby-installable.jar -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby-hash=dfa678d17e1506dd41d051e991cd00b6d0085920db02382e5ca44cda532795bb -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc3-dev)(os_name=linux)(os_arch=amd64))" -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby-Bundle-Version=1.0.0-rc3-dev -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r=http://acme.org/graal/components/linux-amd64/ce/r-installable.jar -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r-hash=72c7a4e78bc05c41a15ee5ccfc1e8955cffc4962ca646856d27c1893c2722287 -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc3-dev)(os_name=linux)(os_arch=amd64))" -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r-Bundle-Version=1.0.0-rc3-dev -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python=http://acme.org/graal/components/linux-amd64/ce/python-installable.jar -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python-hash=4965fd622b18f62ff635421f05a307d5bb7ce5930c0204ea49b276b7368226c7 -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc3-dev)(os_name=linux)(os_arch=amd64))" -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python-Bundle-Version=1.0.0-rc3-dev -Component.1.0.0-rc3-dev_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest.properties deleted file mode 100644 index 0b3dfb5b0978..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest.properties +++ /dev/null @@ -1,21 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -org.graalvm.0.33_linux_amd64: GraalVM 0.33-dev linux amd64 - -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - -Component.0.33_linux_amd64.ruby: postinst2.jar -Component.0.33_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33_linux_amd64.ruby-Bundle-Version: 0.33 -Component.0.33_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest2.properties deleted file mode 100644 index 0b3dfb5b0978..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogInstallTest2.properties +++ /dev/null @@ -1,21 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -org.graalvm.0.33_linux_amd64: GraalVM 0.33-dev linux amd64 - -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - -Component.0.33_linux_amd64.ruby: postinst2.jar -Component.0.33_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33_linux_amd64.ruby-Bundle-Version: 0.33 -Component.0.33_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogMultiFlavours.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogMultiFlavours.properties deleted file mode 100644 index 6d87be728ad4..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/catalogMultiFlavours.properties +++ /dev/null @@ -1,52 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - - -org.graalvm.linux_amd64/1.0.0.0: GraalVM 1.0 -Component.linux_amd64/1.0.0.0/cafebabe/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(java_version=8)(os_arch=amd64))" - -Component.linux_amd64/1.0.0.0/deadbeef/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(java_version=11)(os_arch=amd64))" - -Component.linux_amd64/1.0.0.0/cafebabe/r: ../1.0.0.0/graalvm-fastr.zip -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-Name: FastR -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-Symbolic-Name: R -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - -org.graalvm.linux_amd64/1.0.1.0: GraalVM 1.0.1 -Component.linux_amd64/1.0.1.0/cafebabe/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - - -# Python is intentionally just for version 1.0.1.0 -Component.linux_amd64/1.0.1.0/cafebabe/python: graalvm-python.zip -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-Symbolic-Name: python -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps.properties deleted file mode 100644 index f001c2c7e751..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps.properties +++ /dev/null @@ -1,41 +0,0 @@ -org.graalvm.19.3-dev_linux_amd64: GraalVM 19.3-dev linux amd64 -org.graalvm.19.3_linux_amd64: GraalVM 19.3-dev linux amd64 - -Component.19.3-dev_linux_amd64.org.graalvm.ruby: ruby-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-Name: TruffleRuby 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name: org.graalvm.ruby -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Require-Bundle: org.graalvm.native-image - -Component.19.3-dev_linux_amd64.org.graalvm.r: r-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-Name: FastR 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name: org.graalvm.r -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.r-Require-Bundle: org.graalvm.llvm-toolchain - -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain: llvm-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name: LLVM.org toolchain -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name: org.graalvm.llvm-toolchain -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-ProvideCapability: org.graalvm; edition = "CE" - -Component.19.3-dev_linux_amd64.org.graalvm.native_image: native-image-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-Name: Native Image -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name: org.graalvm.native-image -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Require-Bundle: org.graalvm.llvm-toolchain -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-ProvideCapability: org.graalvm; edition = "CE"; native_version:Version="19.3" - -Component.19.3-dev_linux_amd64.org.graalvm.additional: additional-19.3.zip -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-Name: Additional Component with undeclared dependency -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-Symbolic-Name: org.graalvm.additional -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.additional-Require-Bundle: org.graalvm.unknown diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps2.properties deleted file mode 100644 index 59d2dcf9cfa4..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/cataloginstallDeps2.properties +++ /dev/null @@ -1,37 +0,0 @@ -org.graalvm.19.3-dev_linux_amd64: GraalVM 19.3-dev linux amd64 -org.graalvm.19.3_linux_amd64: GraalVM 19.3-dev linux amd64 - -Component.19.3-dev_linux_amd64.org.graalvm.ruby: ruby-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-Name: TruffleRuby 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name: org.graalvm.ruby -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" - -Component.19.3-dev_linux_amd64.org.graalvm.r: r-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-Name: FastR 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name: org.graalvm.r -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" - -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain: llvm-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name: LLVM.org toolchain -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name: org.graalvm.llvm-toolchain -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-ProvideCapability: org.graalvm; edition = "CE" - -Component.19.3-dev_linux_amd64.org.graalvm.native_image: native-image-deps.jar -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-Name: Native Image -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name: org.graalvm.native-image -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" -Component.19.3-dev_linux_amd64.org.graalvm.llvm_toolchain-Bundle-ProvideCapability: org.graalvm; edition = "CE"; native_version:Version="19.3" - -Component.19.3-dev_linux_amd64.org.graalvm.additional: additional-19.3.zip -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-Name: Additional Component with undeclared dependency -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-Symbolic-Name: org.graalvm.additional -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-Version: 19.3-dev -Component.19.3-dev_linux_amd64.org.graalvm.additional-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=19.3-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-19.3.2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-19.3.2.properties deleted file mode 100644 index 2cd8eeb666a5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-19.3.2.properties +++ /dev/null @@ -1,77 +0,0 @@ -# 19.3.2 Release -org.graalvm.19.3.2_macos_amd64=GraalVM 19.3.2 macos/amd64 -org.graalvm.19.3.2_linux_amd64=GraalVM 19.3.2 linux/amd64 - -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/llvm-toolchain-installable-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-hash=bd236156ba4d47848236a317552d3e8ac11d1f33ee0843f87f65c5f28d59921c -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/llvm-toolchain-installable-java8-linux-amd64-19.3.2.jar -#Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-hash=c48fa0205b8ef891d11d8f3687851a921ca3a4a9928d5072c8f253cf794eb9de -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.native_image=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/native-image-installable-svm-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.native_image-hash=c69e039f1f2896881e627df97149436fb587a52a1f2bb469ee094fa5f467f69b -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.native_image=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/native-image-installable-svm-java8-linux-amd64-19.3.2.jar -#Component.19.3.2_linux_amd64.org.graalvm.native_image-hash=30b59f3eb84c91d742822ea4f2647e882cd04ed68d97954d60cfb7f84dc71719 -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.python=test://github.com/graalvm/graalpython/releases/download/vm-19.3.2/python-installable-svm-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.python-hash=1e95d88cac02694dfad97b4da361282e1b8e427732850d3d5db93ac8fddc8d72 -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.19.3.2_linux_amd64.org.graalvm.python=test://github.com/graalvm/graalpython/releases/download/vm-19.3.2/python-installable-svm-java8-linux-amd64-19.3.2.jar -Component.19.3.2_linux_amd64.org.graalvm.python-hash=0b0404691263ab9ce7c49ea633e82836be80b2fc4caa155b72d1627d1fd48add -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.19.3.2_macos_amd64.org.graalvm.r=test://github.com/oracle/fastr/releases/download/vm-19.3.2/r-installable-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.r-hash=d137b2558a96cc2040c334c3ca42ad4670299de97903d34e11744882f0b0af87 -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.19.3.2_linux_amd64.org.graalvm.r=test://github.com/oracle/fastr/releases/download/vm-19.3.2/r-installable-java8-linux-amd64-19.3.2.jar -Component.19.3.2_linux_amd64.org.graalvm.r-hash=9bc18e48c1cd697b37940d9fecf6f0cef0c2c66ea466834e359c5aa17cfdf286 -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.19.3.2_macos_amd64.org.graalvm.ruby=test://github.com/oracle/truffleruby/releases/download/vm-19.3.2/ruby-installable-svm-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.ruby-hash=c25515aa7a3ed8937b062887bc6377580351831b12fab87733b14f0388a2a56c -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.19.3.2_linux_amd64.org.graalvm.ruby=test://github.com/oracle/truffleruby/releases/download/vm-19.3.2/ruby-installable-svm-java8-linux-amd64-19.3.2.jar -Component.19.3.2_linux_amd64.org.graalvm.ruby-hash=ab0f4c915dade7772206f97589a5a94776cd597d7c4f6b6d8997fedc13cf0c47 -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-20.3.0.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-20.3.0.properties deleted file mode 100644 index 201562b2ac28..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog-20.3.0.properties +++ /dev/null @@ -1,11 +0,0 @@ -# 19.3.2 Release -org.graalvm.19.3.2_macos_amd64=GraalVM 19.3.2 macos/amd64 -org.graalvm.19.3.2_linux_amd64=GraalVM 19.3.2 linux/amd64 - -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain=./dummylang -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.dummylang -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Name=Dummy Language -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 - - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog21patch.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog21patch.properties deleted file mode 100644 index f13b792c907b..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/catalog21patch.properties +++ /dev/null @@ -1,310 +0,0 @@ -# The file was originally downloaded from https://github.com/graalvm -# - -org.graalvm.20.3.0_macos_amd64=GraalVM 20.3.0 macos/amd64 -org.graalvm.20.3.0_linux_amd64=GraalVM 20.3.0 linux/amd64 -org.graalvm.20.3.0_windows_amd64=GraalVM 20.3.0 windows/amd64 - -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/llvm-toolchain-installable-java8-linux-amd64-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-hash=3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7 -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 - -Component.20.3.0_linux_amd64.org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/native-image-installable-svm-java8-linux-amd64-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.native_image-hash=23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7 -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-Version=20.3.0 - -Component.20.3.0_linux_amd64.org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java8-linux-amd64-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.python-hash=e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7 -Component.20.3.0_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.20.3.0_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.20.3.0_linux_amd64.org.graalvm.python-Bundle-Version=20.3.0 -Component.20.3.0_linux_amd64.org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.3.0_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.20.3.0_linux_amd64.org.graalvm.r=https://github.com/oracle/fastr/releases/download/vm-20.3.0/r-installable-java8-linux-amd64-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.r-hash=25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc -Component.20.3.0_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.20.3.0_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.20.3.0_linux_amd64.org.graalvm.r-Bundle-Version=20.3.0 -Component.20.3.0_linux_amd64.org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.3.0_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.20.3.0_linux_amd64.org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.3.0/ruby-installable-svm-java8-linux-amd64-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.ruby-hash=cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d -Component.20.3.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.20.3.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.20.3.0_linux_amd64.org.graalvm.ruby-Bundle-Version=20.3.0 -Component.20.3.0_linux_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.3.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.20.3.0_linux_amd64.org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/wasm-installable-svm-java8-linux-amd64-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.wasm-hash=98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a -Component.20.3.0_linux_amd64.org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.20.3.0_linux_amd64.org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.wasm-Bundle-Name=GraalWasm -Component.20.3.0_linux_amd64.org.graalvm.wasm-Bundle-Version=20.3.0 -Component.20.3.0_linux_amd64.org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm - -# 20.3.1 Release -org.graalvm.20.3.1_macos_amd64=GraalVM 20.3.1 macos/amd64 -org.graalvm.20.3.1_linux_amd64=GraalVM 20.3.1 linux/amd64 -org.graalvm.20.3.1_windows_amd64=GraalVM 20.3.1 windows/amd64 - -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1/llvm-toolchain-installable-java8-darwin-amd64-20.3.1.jar -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-hash=64a11d23a49396f15181ee534dccab58710c197bc6657f7438086f28bb07c0b3 -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.3.1 -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-x-GraalVM-Stability=supported -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-Created-By=1.8.0_91 (Oracle Corporation) -Component.20.3.1_macos_amd64.org.graalvm.llvm_toolchain-Manifest-Version=1.0 -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1/llvm-toolchain-installable-java8-linux-amd64-20.3.1.jar -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-hash=0d81247ee2b6a0fb6c47cfdb56c7eec09a86b395f7888ff0d504c62695c19aa7 -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.3.1 -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-x-GraalVM-Stability=supported -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-Created-By=1.8.0_91 (Oracle Corporation) -Component.20.3.1_linux_amd64.org.graalvm.llvm_toolchain-Manifest-Version=1.0 - -Component.20.3.1_linux_amd64.org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1/native-image-installable-svm-java8-linux-amd64-20.3.1.jar -Component.20.3.1_linux_amd64.org.graalvm.native_image-hash=efd86f9dc5dadffe1c2d8deb0abee6954a2fa31d74e9f284d5218a403825d090 -Component.20.3.1_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.20.3.1_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.1_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.20.3.1_linux_amd64.org.graalvm.native_image-Bundle-Version=20.3.1 -Component.20.3.1_linux_amd64.org.graalvm.native_image-x-GraalVM-Stability=earlyadopter -Component.20.3.1_linux_amd64.org.graalvm.native_image-Created-By=1.8.0_91 (Oracle Corporation) -Component.20.3.1_linux_amd64.org.graalvm.native_image-Manifest-Version=1.0 - - -# 20.3.1.2 Release -org.graalvm.20.3.1.2_macos_amd64=GraalVM 20.3.1.2 macos/amd64 -org.graalvm.20.3.1.2_linux_amd64=GraalVM 20.3.1.2 linux/amd64 -org.graalvm.20.3.1.2_windows_amd64=GraalVM 20.3.1.2 windows/amd64 - -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1.2/llvm-toolchain-installable-java8-linux-amd64-20.3.1.2.jar -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-hash=ee711f90ec8ca14830ad52159ae4bd36ecf4fa7d7ae9f687b04ebfcb481b3200 -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.3.1.2 -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-x-GraalVM-Stability=supported -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-Created-By=1.8.0_91 (Oracle Corporation) -Component.20.3.1.2_linux_amd64.org.graalvm.llvm_toolchain-Manifest-Version=1.0 - -Component.20.3.1.2_linux_amd64.org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1.2/native-image-installable-svm-java8-linux-amd64-20.3.1.2.jar -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-hash=42cb5e3fb6f9098ceb7d76731e7e510ff626c968f6d972b24cb28e86cfb66b10 -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-Bundle-Version=20.3.1.2 -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-x-GraalVM-Stability=earlyadopter -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-Created-By=1.8.0_91 (Oracle Corporation) -Component.20.3.1.2_linux_amd64.org.graalvm.native_image-Manifest-Version=1.0 - -org.graalvm.20.3.1.3_macos_amd64=GraalVM 20.3.1.3 macos/amd64 -org.graalvm.20.3.1.3_linux_amd64=GraalVM 20.3.1.3 linux/amd64 -org.graalvm.20.3.1.3_windows_amd64=GraalVM 20.3.1.3 windows/amd64 - - -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1.3/llvm-toolchain-installable-java8-linux-amd64-20.3.1.3.jar -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-hash=ee711f90ec8ca14830ad52159ae4bd36ecf4fa7d7ae9f687b04ebfcb481b3200 -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1.3)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-Bundle-Version=20.3.1.3 -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-x-GraalVM-Stability=supported -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/20.3.1.3/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.llvm_toolchain-Manifest-Version=1.0 - -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.1.3/native-image-installable-svm-java8-linux-amd64-20.3.1.3.jar -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-hash=42cb5e3fb6f9098ceb7d76731e7e510ff626c968f6d972b24cb28e86cfb66b10 -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.1.3)(os_name=linux)(os_arch=amd64)(java_version=8))" -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-Bundle-Version=20.3.1.3 -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-x-GraalVM-Stability=earlyadopter -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-Created-By=1.8.0_91 (Oracle Corporation) -#Component.20.3.1.3_linux_amd64.org.graalvm.native_image-Manifest-Version=1.0 - -# 21.0.0 Release -org.graalvm.macos_amd64/21.0.0.0=GraalVM 21.0.0.0 macos/amd64 -org.graalvm.linux_amd64/21.0.0.0=GraalVM 21.0.0.0 linux/amd64 -org.graalvm.windows_amd64/21.0.0.0=GraalVM 21.0.0.0 windows/amd64 - -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0/espresso-installable-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-hash=a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0 -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-Bundle-Symbolic-Name=org.graalvm.espresso -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-Bundle-Name=Java on Truffle -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-x-GraalVM-Working-Directories=jre/languages/java -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-Created-By=1.8.0_162 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/a4a4d5f99097b4282e1064b998348df73d90e104effd1aae5449ed6bb675ddc0/org.graalvm.espresso-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0/llvm-toolchain-installable-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-hash=fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7 -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-x-GraalVM-Stability=supported -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/fcfa25d4857af0a43893c30c9186b6d4c637fa86a796907e3c97ef9375cfc7b7/org.graalvm.llvm_toolchain-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0/native-image-installable-svm-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-hash=8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842 -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-x-GraalVM-Stability=earlyadopter -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/8f6976b2a9a40d35df50402a3e893af41a6a6bc01301851a91672106d313f842/org.graalvm.native_image-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python=https://localhost/do-not-use/oracle/graalpython/releases/download/vm-21.0.0/python-installable-svm-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-hash=212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6 -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/212dff312cdc2946e5a629714b2da0a540c966567a80b4df76ba66591cb1a7a6/org.graalvm.python-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r=https://localhost/do-not-use/oracle/fastr/releases/download/vm-21.0.0/r-installable-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-hash=5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9 -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/5a677dcd6b04d313a23fdd75bd91a705c55a127fe124adfea703e2771296aeb9/org.graalvm.r-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby=https://localhost/do-not-use/oracle/truffleruby/releases/download/vm-21.0.0/ruby-installable-svm-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-hash=83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788 -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/83fcbc90248f5381cc95fefdd991c2854ff0e0e334782796b418fefaf4455788/org.graalvm.ruby-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0/wasm-installable-svm-java8-linux-amd64-21.0.0.jar -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-hash=6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36 -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-Bundle-Name=GraalWasm -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-Bundle-Version=21.0.0 -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.0/6501ce36f0c50b76d0b392af325e90a60cf40664c09ab97eca09c53ccd5b8f36/org.graalvm.wasm-Manifest-Version=1.0 - -# 21.0.0.2 Release -# 21.0.0.2 entry intentionally commented out -#org.graalvm.macos_amd64/21.0.0.2=GraalVM 21.0.0.2 macos/amd64 -#org.graalvm.linux_amd64/21.0.0.2=GraalVM 21.0.0.2 linux/amd64 -#org.graalvm.windows_amd64/21.0.0.2=GraalVM 21.0.0.2 windows/amd64 - -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/espresso-installable-java8-linux-amd64-21.0.0.2.jar -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-hash=21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976 -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-Bundle-Symbolic-Name=org.graalvm.espresso -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-Bundle-Name=Java on Truffle -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-Bundle-Version=21.0.0.2 -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-x-GraalVM-Working-Directories=jre/languages/java -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.2/21aff622b4b97438f01f0bbd8be0c34f7ec6b546f8caa4d683a2bf25fef46976/org.graalvm.espresso-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/llvm-toolchain-installable-java8-linux-amd64-21.0.0.2.jar -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-hash=9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794 -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-Bundle-Version=21.0.0.2 -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-x-GraalVM-Stability=supported -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.2/9125760257f3ddb5a5118f2ec854069ab1731b3689139611c73b6b00d32f8794/org.graalvm.llvm_toolchain-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/native-image-installable-svm-java8-linux-amd64-21.0.0.2.jar -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-hash=e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-Bundle-Version=21.0.0.2 -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-x-GraalVM-Stability=earlyadopter -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.2/e2a182c1f79d8a97b537b843eb65e15ef5ebdd088ad01acd606bf26b1846612e/org.graalvm.native_image-Manifest-Version=1.0 - -# For Python patch, allow to cooperate with an older release: - -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python=https://localhost/do-not-use/oracle/graalpython/releases/download/vm-21.0.0.2/python-installable-svm-java8-linux-amd64-21.0.0.2.jar -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-hash=842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1 -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Bundle-Version=21.0.0.2 -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.2/842c1e376a3d78700f131baf5883b654d04b1ca7503740e97436c1572ba6c4b1/org.graalvm.python-Manifest-Version=1.0 - -# Do not distribute R -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r=https://localhost/do-not-use/oracle/fastr/releases/download/vm-21.0.0.2/r-installable-java8-linux-amd64-21.0.0.2.jar -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-hash=488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Bundle-Name=FastR -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Bundle-Version=21.0.0.2 -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-x-GraalVM-Stability=experimental -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Created-By=1.8.0_91 (Oracle Corporation) -#Component.linux_amd64/21.0.0.2/488b0357e183fcbf78c2f64da944778d61b8d4e3e68213fe6d0b80937618742b/org.graalvm.r-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby=https://localhost/do-not-use/oracle/truffleruby/releases/download/vm-21.0.0.2/ruby-installable-svm-java8-linux-amd64-21.0.0.2.jar -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-hash=6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Bundle-Version=21.0.0.2 -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.2/6f952d0b68e3b38f24c66f1368d752869fafd8cb1ce1c4a7260d738905b25e7e/org.graalvm.ruby-Manifest-Version=1.0 - -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm=https://localhost/do-not-use/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0.2/wasm-installable-svm-java8-linux-amd64-21.0.0.2.jar -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-hash=bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939 -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=21.0.0.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-Bundle-Name=GraalWasm -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-Bundle-Version=21.0.0.2 -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-x-GraalVM-Stability=experimental -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-Created-By=1.8.0_91 (Oracle Corporation) -Component.linux_amd64/21.0.0.2/bb90889bf73c3f9a937dde0af1e1b6fc7389ec3f61370511cac6849811f53939/org.graalvm.wasm-Manifest-Version=1.0 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvm-20.2-with-updates.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvm-20.2-with-updates.properties deleted file mode 100644 index 5ffe69dd347d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvm-20.2-with-updates.properties +++ /dev/null @@ -1,170 +0,0 @@ -org.graalvm.macos_amd64/20.3.0.0=GraalVM 20.3.0.0 macos/amd64 -org.graalvm.windows_amd64/20.3.0.0=GraalVM 20.3.0.0 windows/amd64 -org.graalvm.linux_aarch64/20.3.0.0=GraalVM 20.3.0.0 linux/aarch64 -org.graalvm.linux_amd64/20.3.0.0=GraalVM 20.3.0.0 linux/amd64 - -# Foged up 20.2.0 core -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm=./graalvm-linux-ce-java11-20.2.0.jar -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-hash=db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Version=20.2.0 - -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm=./graalvm-linux-ce-java11-20.3.0.jar -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-hash=db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm=./graalvm-linux-ce-java8-20.3.0.jar -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-hash=9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-Version=20.3.0 - -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/llvm-toolchain-installable-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-hash=31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/llvm-toolchain-installable-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-hash=3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7 -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/native-image-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-hash=6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726 -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/native-image-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-hash=23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7 -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-hash=7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-x-GraalVM-Working-Directories=languages/python -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-hash=e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7 -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r=https://github.com/oracle/fastr/releases/download/vm-20.3.0/r-installable-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-hash=79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1 -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-x-GraalVM-Working-Directories=languages/R -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r=https://github.com/oracle/fastr/releases/download/vm-20.3.0/r-installable-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-hash=25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.3.0/ruby-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-hash=876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-x-GraalVM-Working-Directories=languages/ruby -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.3.0/ruby-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-hash=cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/wasm-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-hash=13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9 -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-Name=GraalWasm -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-x-GraalVM-Working-Directories=languages/wasm -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/wasm-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-hash=98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-Name=GraalWasm -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java8-darwin-amd64-20.3.0.jar -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-hash=874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122 -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-Name=Graal.Python -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-Version=20.3.0 -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - - -# 20.2.0 Release -org.graalvm.20.2.0_macos_amd64=GraalVM 20.2.0 macos/amd64 -org.graalvm.20.2.0_linux_amd64=GraalVM 20.2.0 linux/amd64 -org.graalvm.20.2.0_windows_amd64=GraalVM 20.2.0 windows/amd64 - -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/llvm-toolchain-installable-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-hash=a02e6554e1211cff5b635c728d74b91ad18165058d3175004079be1412cf04c9 -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/native-image-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.native_image-hash=6b5403e27282847acce180f0ae9637c3f26678f27047bbd5dfed92a5bef73ab2 -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.2.0/python-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.python-hash=ff050939c8abf5827928c9b17800e6e153eb1bc57a81b9f4e579ef87c5b94856 -Component.20.2.0_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.20.2.0_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.20.2.0_linux_amd64.org.graalvm.python-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.2.0_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.20.2.0_linux_amd64.org.graalvm.r=https://github.com/oracle/fastr/releases/download/vm-20.2.0/r-installable-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.r-hash=fdd3b3124b57a66d50556e55f68c39e23a42743afe0010987768149ba93b86b4 -Component.20.2.0_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.20.2.0_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.20.2.0_linux_amd64.org.graalvm.r-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.2.0_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.20.2.0_linux_amd64.org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.2.0/ruby-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.ruby-hash=5ec06f17f908d1a5eacf93019505d755ce128081f3bc0eca02d4ba59c3dc9c67 -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.2.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.20.2.0_linux_amd64.org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/wasm-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.wasm-hash=c6ac9cd98de8685ea913d07ebce59fc901104c02a7683e08641ef933ab6227af -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-Name=GraalWasm -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvmee-20.2-with-updates.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvmee-20.2-with-updates.properties deleted file mode 100644 index befe2b68cec7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/graalvmee-20.2-with-updates.properties +++ /dev/null @@ -1,154 +0,0 @@ -org.graalvm.macos_amd64/20.3.0.0=GraalVM 20.3.0.0 macos/amd64 -org.graalvm.windows_amd64/20.3.0.0=GraalVM 20.3.0.0 windows/amd64 -org.graalvm.linux_aarch64/20.3.0.0=GraalVM 20.3.0.0 linux/aarch64 -org.graalvm.linux_amd64/20.3.0.0=GraalVM 20.3.0.0 linux/amd64 - -# Foged up 20.2.0 core -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm=./graalvm-linux-ce-java11-20.2.0.jar -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-hash=db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/20.2.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Version=20.2.0 - -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm=./graalvm-linux-ce-java11-20.3.0.jar -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-hash=db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/20.3.0.0/db126634379452efd7e47d6fdc47a56693eb326afb1def6dae1fba1c7a2ac2ae/org.graalvm-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm=./graalvm-linux-ce-java8-20.3.0.jar -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-hash=9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/20.3.0.0/9894f6a6b3fab9624f5b658ce37c06cbd79041716a2247f48b0575bffa82ceea/org.graalvm-Bundle-Version=20.3.0 - -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/llvm-toolchain-installable-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-hash=31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/20.3.0.0/31c27fc00adcb17b6eea5d9cf5952bee43b4fdb8c43808bb98b4925916b2470d/org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/llvm-toolchain-installable-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-hash=3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7 -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.linux_amd64/20.3.0.0/3c2a58c66c789768bbbb5e420bde73e5d593144311365c1da5f15b7aeea05ba7/org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/native-image-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-hash=6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726 -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/20.3.0.0/6e67f3c5cc329956fe9bc33d571c2e771eff8f4f541bca275bb62744026d3726/org.graalvm.native_image-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/native-image-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-hash=23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7 -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/20.3.0.0/23c4d1d7845d5113971fe5b9173eaa244f0f514a9b806191bea523f12985ebe7/org.graalvm.native_image-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-hash=7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/7feeea85cba558266561aadf09068fcb4ef6b0444622beecb3eb6721f4136f8d/org.graalvm.python-x-GraalVM-Working-Directories=languages/python -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-hash=e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7 -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/e4ecee04a4b47c81444df63f3e7b1f80e0149dde928627126690f29ce1ac53c7/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r=https://github.com/oracle/fastr/releases/download/vm-20.3.0/r-installable-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-hash=79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1 -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/79d129d572563fe7179009d162160557444b0f7e0b4dbf460d0ba25ca65a63b1/org.graalvm.r-x-GraalVM-Working-Directories=languages/R -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r=https://github.com/oracle/fastr/releases/download/vm-20.3.0/r-installable-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-hash=25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/25aa20f6ed3190f18a328a31ca78c27bbeaaf19f1555e8fd30c84c2d2f21b5bc/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.3.0/ruby-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-hash=876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/876932cbb9a34a0a10d7c014aef23047a7367fa58405ee1f200f731ac521694d/org.graalvm.ruby-x-GraalVM-Working-Directories=languages/ruby -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.3.0/ruby-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-hash=cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.linux_amd64/20.3.0.0/cdb0bd76394fe75cc9caf53ad20f30cda8b166def5d90ce5881ed2b509d9286d/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/wasm-installable-svm-java11-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-hash=13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9 -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=11))" -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-Name=GraalWasm -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/13cf6fee93313beee36fd9d3ab4e627b05855e142a4172d228dc70efe5731fe9/org.graalvm.wasm-x-GraalVM-Working-Directories=languages/wasm -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/wasm-installable-svm-java8-linux-amd64-20.3.0.jar -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-hash=98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-Name=GraalWasm -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-Bundle-Version=20.3.0 -Component.linux_amd64/20.3.0.0/98baea8ebff1de6fe7a891922e06695ac6e88f62b815de07e465b0ba03659b8a/org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python=https://github.com/graalvm/graalpython/releases/download/vm-20.3.0/python-installable-svm-java8-darwin-amd64-20.3.0.jar -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-hash=874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122 -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-Name=Graal.Python -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Bundle-Version=20.3.0 -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.macos_amd64/20.3.0.0/874981500a64418e45f89ef06eff3624506a8c8b7e4ebf6cf5bce8834758f122/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - - -# 20.2.0 Release -org.graalvm.20.2.0_macos_amd64=GraalVM 20.2.0 macos/amd64 -org.graalvm.20.2.0_linux_amd64=GraalVM 20.2.0 linux/amd64 -org.graalvm.20.2.0_windows_amd64=GraalVM 20.2.0 windows/amd64 - -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/llvm-toolchain-installable-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-hash=a02e6554e1211cff5b635c728d74b91ad18165058d3175004079be1412cf04c9 -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.2.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.native_image=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/native-image-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.native_image-hash=6b5403e27282847acce180f0ae9637c3f26678f27047bbd5dfed92a5bef73ab2 -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.20.2.0_linux_amd64.org.graalvm.native_image-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.ruby=https://github.com/oracle/truffleruby/releases/download/vm-20.2.0/ruby-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.ruby-hash=5ec06f17f908d1a5eacf93019505d755ce128081f3bc0eca02d4ba59c3dc9c67 -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.20.2.0_linux_amd64.org.graalvm.ruby-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.20.2.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.20.2.0_linux_amd64.org.graalvm.wasm=https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.2.0/wasm-installable-svm-java8-linux-amd64-20.2.0.jar -Component.20.2.0_linux_amd64.org.graalvm.wasm-hash=c6ac9cd98de8685ea913d07ebce59fc901104c02a7683e08641ef933ab6227af -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-Symbolic-Name=org.graalvm.wasm -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.2.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-Name=GraalWasm -Component.20.2.0_linux_amd64.org.graalvm.wasm-Bundle-Version=20.2.0 -Component.20.2.0_linux_amd64.org.graalvm.wasm-x-GraalVM-Working-Directories=jre/languages/wasm diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/license.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/license.txt deleted file mode 100644 index 6a0785d9ed12..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/license.txt +++ /dev/null @@ -1 +0,0 @@ -License -- dummy testing license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/llvm-deps-19.3.2.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/llvm-deps-19.3.2.jar deleted file mode 100644 index aa62ec1cd74b0589a66492c84ffca3c0bc299fcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 479 zcmWIWW@Zs#VBp|ju*tX_zyJhHAOZ+D8CV#6T|*poJ^kGD|D9rBU}gw_E54ED8Ti2Z zOYlyhLKa2_1`!4sgkoPuKTkK;;1E4ux6lwy2IdOKhWJb%F0J5ZU}Sm04AcT5Qv1$w z9WoGTd0*Rgp?OO?%NixAldg{Xp)L!rZ^}*X%@Ov!oOJ)*FYZUF3F+x}X%}BGsor%` zwd{PHa=1sg)0pkEu*O^6xc|=KscfPD_`XSoMKR=Px9z>K-$^NVZO^k5i)3Z7+BbXm zn4LPM8lw=rBIf(yS(6t#sq2c@8F1W7yR|Rik>@855w>N1rTd*1Tsr%5(K*lft0HpAWF#rGn diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/native-image-deps-19.3.2.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/native-image-deps-19.3.2.jar deleted file mode 100644 index 19496b2caaab90b8e5d904842dee6aedd918efcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmWIWW@Zs#VBp|jaLc$HzyJhHAOZ+D8CV#6T|*poJ^kGD|D9rBU}gw_D}I#b8JKbD zJLe&wLUl$41`!4sgkoPuKTkK;;1E4ux6lwy2IdaOhWI)lF0J5ZU}Sm0%)kI9a{Ilx z4>|C(y#K8&#(zm}+XLo{Uiw^BK`sYZA2GY;Q5L@acGCa7{b7zDgif4!l5C{ydu+wE z1%}huY(iIfIQJ!8v)COauN!>JZO!S$cNhznF0TJ*yQ^tUXKKC>@1lS1_a3cPX)oS! zXyS~Tzs|Ex32$^4SD(8;dds7QSpg?!tEAZTiB1 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/release21ceWithEE.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/release21ceWithEE.properties deleted file mode 100644 index 047d8c250b57..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/release21ceWithEE.properties +++ /dev/null @@ -1,15 +0,0 @@ -JAVA_VERSION="1.8.0_272" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" jvmci:0bbce9bf3339 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438" -GRAALVM_VERSION="20.2.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} - -component_catalog_url=test://www.graalvm.org/graalvm-20.2-with-updates.properties -component_catalog_label=GitHub CE Components -component_catalog_editionLabel=GraalVM CE - -ee_component_catalog_10_url=test://www.graalvm.org/graalvmee-20.2-with-updates.properties -ee_component_catalog_10_label=GitHub EE Components -ee_component_catalog_editionLabel=GraalVM EE diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/releases.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/releases.json deleted file mode 100644 index edd43b610f18..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/data/releases.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "Releases": { - "19.3.3-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.3", - "catalog": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - } - }, - "19.3.3-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk11", - "license": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk11", - "version": "19.3.3", - "catalog": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_3/19_3_3_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-windows-amd64-19.3.3.zip" - } - } - }, - "19.3.2-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.2", - "catalog": "catalog-19.3.2.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - } - }, - "19.3.2-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk11", - "license": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk11", - "version": "19.3.2", - "catalog": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_2/19.3.2_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "test://oca.opensource.oracle.com/gds/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-windows-amd64-19.3.2.zip" - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/graalvm-fastr.zip b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/graalvm-fastr.zip deleted file mode 100644 index 9a7d85a0a2d5e3f0a9a7ce8e0a5cfa49260cca16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180590 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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%0A44~!$O7vb%jg6S7<$ODwuZmO8u1t|!&f+3c|*)v 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 LBq<04&5-{A{`83k diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/graalvm-ruby.zip b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/graalvm-ruby.zip deleted file mode 100644 index 0d7c1f429df118502f94f656f03e29c9d76f57e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180590 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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%0A44~!$O7vb%jg6S7<$ODwuZmO8u1t|!&f+3c|*)v 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/META-INF/MANIFEST.MF deleted file mode 100644 index 58ebd2e1afa1..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/META-INF/MANIFEST.MF +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.python -Bundle-Name: GraalPython -Bundle-Version: 1.0 -Bundle-RequireCapability: org.graalvm; filter := "(&(graalvm_version=19.3.3)(os_arch=amd64))" -x-GraalVM-License-Type: Python License -x-GraalVM-License-Path: license.txt diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/license.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/license.txt deleted file mode 100644 index 647650e15028..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.python/license.txt +++ /dev/null @@ -1 +0,0 @@ -Testing Python license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/META-INF/MANIFEST.MF deleted file mode 100644 index df3521b06803..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/META-INF/MANIFEST.MF +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Name: Truffle Ruby -Bundle-Version: 1.0 -Bundle-RequireCapability: org.graalvm; filter := "(&(graalvm_version=19.3.3)(os_arch=amd64))" -x-GraalVM-License-Type: Testing License -x-GraalVM-License-Path: license.txt diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/LICENCE.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/LICENCE.md deleted file mode 100644 index 3b94ae810e9b..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/LICENCE.md +++ /dev/null @@ -1,12 +0,0 @@ -# TruffleRuby Licence - -TruffleRuby is copyright (c) 2013-2017 Oracle and/or its -affiliates, and is made available to you under the terms of three licenses: - -* Eclipse Public License version 1.0 -* GNU General Public License version 2 -* GNU Lesser General Public License version 2.1 - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/README.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/README.md deleted file mode 100644 index 9cec298cd331..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/jre/languages/ruby/README.md +++ /dev/null @@ -1,134 +0,0 @@ -![TruffleRuby logo](logo/png/truffleruby_logo_horizontal_medium.png) - -A high performance implementation of the Ruby programming language. Built on the -GraalVM by [Oracle Labs](https://labs.oracle.com). - -## Authors - -The main authors of TruffleRuby in order of joining the project are: - -* Chris Seaton -* Benoit Daloze -* Kevin Menard -* Petr Chalupa -* Brandon Fish -* Duncan MacGregor - -Additionally: - -* Thomas Würthinger -* Matthias Grimmer -* Josef Haider -* Fabio Niephaus -* Matthias Springer -* Lucas Allan Amorim -* Aditya Bhardwaj - -Collaborations with: - -* [Institut für Systemsoftware at Johannes Kepler University - Linz](http://ssw.jku.at) - -And others. - -The best way to get in touch with us is to join us in -https://gitter.im/graalvm/truffleruby, but you can also Tweet to @chrisgseaton, -or email chris.seaton@oracle.com. - -## Mailing list - -Announcements about GraalVM, including TruffleRuby, are made on the -[graalvm-dev](https://oss.oracle.com/mailman/listinfo/graalvm-dev) mailing list. - -## System Compatibility - -TruffleRuby is actively tested on these systems: - -* Ubuntu 16.04 LTS -* Fedora 26 -* macOS 10.13 - -You need to [install LLVM](doc/user/installing-llvm.md) to build and run C -extensions and [`libssl`](doc/user/installing-libssl.md) to use `openssl`. You -may also need to set up a [UTF-8 locale](doc/user/utf8-locale.md) - -Oracle Linux is not currently supported due to not having a good way to install -a recent LLVM. - -## Current Status - -TruffleRuby is progressing fast but is currently probably not ready for you to -try running your full Ruby application on. Support for critical C extensions -such as OpenSSL and Nokogiri is missing. - -TruffleRuby is ready for experimentation and curious end-users to try on their -gems and smaller applications. - -### Common questions about the status of TruffleRuby - -#### Do you run Rails? - -We do run Rails, and pass the majority of the Rails test suite. But we are -missing support for OpenSSL, Nokogiri, and ActiveRecord database drivers -which makes it not practical to run real Rails applications at the moment. - -#### What is happening with AOT, startup time, and the SubstrateVM? - -You don't need a JVM to run TruffleRuby. With the -[SubstrateVM](doc/user/svm.md) -it is possible to produce a single, statically linked native binary executable -version of TruffleRuby, which doesn't need any JVM to run. - -This SubstrateVM version of TruffleRuby has startup performance and memory -footprint more similar to MRI than TruffleRuby on the JVM or JRuby. There are -[instructions](doc/user/svm.md) -for using it as part of GraalVM. - -#### Can TruffleRuby run on a standard JVM? - -It is possible to [run on an unmodified JDK 9](doc/user/using-java9.md) but you -will have to build Graal yourself and we recommend using GraalVM instead. - -#### How do I install gems? - -TruffleRuby cannot install gems out of the box yet, however there are -[temporary workarounds](doc/user/installing-gems.md) -which can be used to get it working. - -## Getting Started - -The best way to get started with TruffleRuby is via the GraalVM, which includes -compatible versions of everything you need as well as TruffleRuby. - -http://www.oracle.com/technetwork/oracle-labs/program-languages/ - -Inside the GraalVM is a `bin/ruby` command that runs TruffleRuby. -See [Using TruffleRuby with GraalVM](doc/user/using-graalvm.md) -instructions. - -You can also build TruffleRuby from source, see the -[Building Instructions](doc/contributor/workflow.md). - -## Documentation - -Documentation is in [`doc`](doc). - -## Licence - -TruffleRuby is copyright (c) 2013-2017 Oracle and/or its -affiliates, and is made available to you under the terms of three licenses: - -* Eclipse Public License version 1.0 -* GNU General Public License version 2 -* GNU Lesser General Public License version 2.1 - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. - -## Attribution - -TruffleRuby is a fork of [JRuby](https://github.com/jruby/jruby), combining it -with code from the [Rubinius](https://github.com/rubinius/rubinius) project, and -also containing code from the standard implementation of Ruby, -[MRI](https://github.com/ruby/ruby). diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/license.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/license.txt deleted file mode 100644 index 66529f4b4d4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/license.ruby/license.txt +++ /dev/null @@ -1 +0,0 @@ -Testing Ruby License \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/llvm-deps.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/llvm-deps.jar deleted file mode 100644 index 3eacef6c16f4915510ee2b2e685c45886b35d00a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 482 zcmWIWW@Zs#VBp|ju*tX_zyJhHAOZ+D8CV#6T|*poJ^kGD|D9rBU}gw_E3VDF9Pr>> zj@=%hLLNp21`!4sgkoPuKTkK;;1E4ux6lwy2IjiCZ{o^P0GpKz#^`@wAs zTpS)*`0m)qT6ip>jB(}O7gOb> ze>=ZDiu2SCD`=kV^75Aay-9OatrD9H9NNF+%DooXdy^^mveM49y~v8VcYwHcfXm}C(c&a_q}m0A$mb!4*NCM6y6A~_lyDFj7%axU*ifma0tQ) zlwbsDm1Blz#SBIXuqI%LGBh;m0!g@5lt5*L1S(p926(fwfwVIL;Zz`P4l;%T0QO^$ A_W%F@ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/native-image-deps.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/native-image-deps.jar deleted file mode 100644 index 0c2519744e768310a091526d65c6ac27f974b923..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 493 zcmWIWW@Zs#VBp|jaLc$HzyJhHAOZ+D8CV#6T|*poJ^kGD|D9rBU}gw_D`w8U9MIss zefDvnLVZRC1`!4sgkoPuKTkK;;1E4ux6lwy24=A(Z{mc2xU_Rpg6(gK#?+m35Z|0B z6RUXO{^M{N{v*z7kL5)`U0nskI8Lx`!%APzAxEFO!-@)w__9L67cFc9yjj^m+L?fG LDv)*p8N&bo39yjO diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/postinst.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/postinst.jar deleted file mode 100644 index a611a3ba3de13bf9e70c617eb6bdbfbb287696bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 780 zcmWIWW@Zs#VBp|j;ExOTF_-QGsn?3 zui4ua*+u0i2{`eUHE9seUrqzKU@)&^~}7N7LE2uq*#g((r-UzAuvhzGbYW>-^yB$UINv{2 z$j&X1v2Uz*TJ7u7RKzI0S%358&);&Dbk}vs-+yi_zira2I>oiScFsGmzv=s*j{!e+ zotZAt^v0n6qoUnT0q+|-mOnlHdDpJk&<$1Vkc85$=6&C{H1F-RZB{ZiRiE%IAiL!3m88ehirNK) z6u)SQ)^kVst4pfXzWB+-IMK1T$62HG#f;gnn%=gm-;@w3ob@wNa*^3Sv9KZ`p;P8c zto!Cf+$yas>r1$LF)(q;t(HeWD%q#pF)V!D`>{HY;oHVbnsVW6mv{cDj&pyn`%id3 zXY0gu-Zmc;`ZRAmp5w){r|GRGWBHF*!K${@|BM0Nj7%cH_`{WA;3)yjfTkaiCN2it zDF&g*6gB-YGRZOHN-^8&3acKoN10%}|W(Ec@5jxR7`?iC?(f7YZoHY)% zc|?1>bUfIuHf2Kd+y`BAc+!^2dPcv0x8k>YpT^&JvXN#g)ltvh{<(L1=I(pd+`0VgX=U`^8zCDi*VRq4o?dTf9saer=tKisiK0XWLrs58YIs41 zmV?R)K^wCa_S^tQZDm#dL>|GnOXN?=KUk4`e!&T!vz$w2-jj+o-g;x_RvU$uCxTT| zy7sf`{@l!Sss6>z#)cCM?2ai;aVk0ETYB(Y)1DljE(`wJTWu?NuO9O9d(^tfZOMV@ z#@@U2&g%)Tv9i?a37Q=+$L@W_;&)Sas3yNS!F#|i%mV&l$i%H;Sf+a2;($C7-+)d4yhTkK(~M}50VK*rAd`wcU%LS0K#ad zgrpXiC?x0Sm89mCSSje~gWL_W8KjRZz?+dt1eiQ=WeA{MNC28WK$^H1aAydF4pSf# zDSI$7$uZ-~AQE6*!2H6{&=`ZP4JEs$m0tdWK=2{YP|P0E6r1c^kTX;>o=VH#!>BKvp^l4+0#1)7K@G6TF>*+9Nz1Hui! Lz~Tp%77Ppk1iD;$ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/r-deps.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/r-deps.jar deleted file mode 100644 index 22d441a31e1e02320ec930381323bde62279bfd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 485 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 mlD)ZpApc}q1dtz0i~mIi2Uu4gmO^#3XGqV=!y z!2O-`9}+f(cIK{z=BCd7hb)u_^}o!9{Qr}6ay9b&rvl2~MM3~HR;5T6MNzs!0RjLl z{T;afwStVKu&A7{D4nfIXo9pfupmOn%>y-77fDgJ4G+W)X?nr_0SO)#Gw*uf&Y3A5 zWo=O@A$al#>XU_Sfp= zKmY((|GkpAsjaP|uKf}Ng3n9s8d)loRW|oKK-mIng>u=e0=|=y=Rr!mq*3CU;gt?@ z;kWyWJ4$3Qx^~`nZZ761dG!2U(VQ7z<1Zrj>Vc4?qDAynv*ee8#iPm4llmI&TaBrC z$7(_Rx);RZ-`K{OsHn`Q3(^}Nw|xo9!{mlK!;i7=IlbIYeCF~kd{)!lEn?-b_ex%? zZW)^F)uok3_pW=ot)8Ozm%qx|3uMx1eOGkx@$y~d^$R%-+RMk@(Jqk;+poAb8aa$O zZsAk|*a3Xs+T?E7E%(Xgn@zF$y4~bRLdGAQi!u1crVAPg^rt!+{R={EE0AkeXBEf~DyGoZ-6(-{rlVHC`!&UXZ&r?kJV$SCKl};z0Dx-sUAS zHHS^1nmettv=@o9!56I~gb5o6d38IA5S}!1!}H~`%;ysquEY*f5D*YTsk0_pmz4@4sO)g>?c?A2Fsa1RTjv9LB7JmxUV?<5(VRoHUt}tXVfWk1u^$-|FPGfl5Hodc zPMrkjW5{E2c$P?TjxWgBT2~vrIkRnMKZCbO*Mx-MF=lVOqsg|A=?mZKP_uls;3`Yx zlGgN`oAXa^$ETX{aIPj*(KUisaR+)a9CcIjVf{_q%_H=`8pVI0d1w2tF?jzP<$r*< zrIXSBYn9x)T8~&}65(Vy2^T5}Q4v$Az{D{-`f|(jzV*n{-qEnA!b!=Soz>i&)L#cm z*xE_C1*zN+?P9}})wu1+21vo%B(2XSIR~)op<77N zhIJjIAM^8Mw)7p!))U?^6m9b>(yuO#`MAZpq9Pyk)@v}@CWTuK-mzejlV0->RKFBH zcd}Whji0*gvUEQGx#9mO@9)DD_MQJ4#QrbuvHu687+Ra!D#^+pFd%e)sPiOA$s$PY zX_Z57L+=k1Y7r6=60u{lqm}34a$h!p`*9yA38;8S5XbJGjJ-+ng4VFFEFb38&ljpc zrfZor7ByZz#xZcyUyLO)0^c=xj>p|-@GD~JnT{E@&M>>Kbs5kaXrM=mlX0s0CB0IO z61!#P0|_nR{Fz2n5x>Y)YA5i2V(VKAycGwx8ArT$CH0r>RKN`Y;f)KneX*HRuHX!@ z&0T{DP7pEV!LXX&$QA6AYr9(%`Q~LL^upNQ=$AqRlAqCR4UHX_X8g*l3OFv09Sdn! znjIosr%U|O*za1%R9Z1;?&+zFIYL1FO*{GJFXp7S&7wBqEDhVf;%=mF!f$VquJ}w;34w07oo954Z;WRRrI7u9B6}J7aMnWg6b6glTy|wasgP@gwe3f zAq%T{22g*oi&PoDp(WU6%@#KlT{_GdOxjCOL{IG&HV1gJxVMJ{P12L3ub~f<6PuVw zDNKe)^LOu;H+*H?OKGs5**W5Ac9N))h-uijJJ%#3QHd97TFF##PM;R(#c&JQ( z-_V$77xuqmq~eOyXxOFzd zeM~1i(W6~G@u_kQ*+RrQsV+0<+VlCefA;9=*9wXC2LS_Syj<2=+_t620Wxp1<38C0bHdx+IGiFGd&HE~g^=cnL$s6eFL&ftPzV9vv_R-S$X_G5m(nn!htxoxP4>vZa z>WvwtJSBV&dnY5FAIndQt@+%_n@gw~ZUsw_tZvJ52A>OWaxbZbo3PbqFe_pgUQW_c zv4otaw{}OatLuKE)z|8hwK9UU$+pCXlq==xdKb@wpoUNT)vK!3r#k6>77xfq2tT>9 zn_sDNrchEZ;Gl}}c#D!z{un8oBbmEyJpX=x$mj2-Fw3cpJ-M?s_jU{Y3btM?iTd6B zrdsYlXL(>-&^|x^^y*{hWlr2ZSN&mi`xV|ES`58tt$*+!kIdV0$_AUI?!CR*HYbgZ z<J%kH#gdccKydZ7RFR39imVtgwk?ql$p+Nw(~T&v3< z{jR&I#ixJ1z~yB;J$H&yqJ12^o5d-Q3MQvTAV-c1v~G9{0%ya*Ywr-)+@p5BWGDz} zuwE-*jg5V0@xeV$rde<_KFRA>Ouh+QSZ*L2#S5^YXm%3h)pWF=P9~ z3JzZnZK$iW`&&r7L{2{$_>m8V)20|Qam7n`ettp(PSvH{Y6x8_5CK8Pap|y9U0bfo zCT0Y^CA&I0iZ z`3i_Sq@PWsN9+bc-_VDEAYxDq34dU;LY9?2&*3&f5-e%OO!|HJ^jXo??nTDkQ0ftr zI}9fKuD(UTW8GvC(An=q#f@1!N=}!ZpoFvp5z&<#ea{{hu^KG{*he`Y4pf+MRFmSi zN5)si<YovmS7 z%~rtIngT+X5^e_R{B8$&Um#0D$?(Tyx;VcuF!gp;> zgR*=0_BkY08V@paRw_|5D5ZtLF$y`6cZ2s{BRqEv2mO&Eayd!L$F=Z5Hoa2?-FS=8 zwBo#1J-nhO{N_dDiITDRY8If zy9aSy-U5)vr`$_~+KaTrb*&sao{4I#wlxfP&#+JF&XGpFZgZw^erI%pPF$VNpy03A zIBqds4tw0h$D$FjYFLHf6?Kr?)5BxZ<0n!g22RY}eS1;~i?lP~)8!p?iI0DHPn{K? zu|~a~j)5En@ik~7c1H$EE`-uROhj=5i_E1}|3=QxC1=6N!WdkMFm^Jo!^Lt4cJ`hw zQ?yjfU^hrFM@q1cO-f4HOypL|39QP6^xplL9`dG?+k(36F1E)8b~6lLZXz}s;tHPV zRFpm;Qa^@xRRjsTvZ>_7cfGrYsXOJih>bzF?@L+56kL+ZKO+IUP$qT!0t=I=B?$q} zai_+cBdMRaZaRPT(v-00~~t26qG>QEG`@KJ+bO+0=RvO=08m@k86My zUwv2mA$sRoF>Y>|!-M#}UfJtGHi073iE^00r66g-{AkcM-6DB-AuQGM^15BksXW{A zE>(p*dtCwV1t6Dp24$p+(b(#uZ(+Po$ZBVcV1_qkkgQceKxCb%VSQrXB)(lc*jkCW znc5kbIZ-Wc*+#S6`Aimti6((`=5K0rxH+9ERPybnjB;->GvnRhW! zR579kP>+pCLp1iXC9z7mknRkCTL8%S$~~=DJR)b;ttaoDY*A6do_NDNIViqWIy(~f zW3hP|j;RrH9=Kw@U&cb@68byWanMZ^=Zc0IfmGo#582sRp>eRgg-Vzy%crlWUUOoB zX*`QadbNgiiX|sY*K1V~fS6hh$GE}c?w2T5XCpYJ#-H3nT8Zn=7(~q$yXli-pq~L% zOZA(Sj)!r9f_7b< z27ICR8}|o?*ZIL$+#JTln2bhK=3C9(m2mL-pGw-xK&)5ZCw7P6kKg$J2nGHl*Y)pt zr~f7c@;65QACgu7P3ZFvB^y(7Lz{m~o?s8nJDk7*0CbT908szep~ru!8afynTbR-^ z(J|1uc(`n9X*(aZp#BZi`z%VBpJCKHC9_*3^HQ4G6+08%N!qzRLnIW0(n&A^nyS9v z^PufgOvrt!&B^O6_V@O5dLD9tA@8{PqxI6jN%_u|T;+V9CbEB&RxB4I?T>Gu?%>yB z7xISKZ+5e)s<)iDO@M&GJtMg*tcP7j&bC6bz z+?KRa85imSds~V52!55zz~Zy;m`yRR?D(TYZ%mIuE$iRl<&P1<={5nS0Eu?~hvbk0 zCuaGl@T)7wnmQ~P2gIhM6$#DF+iQH2P+8#0l=xcmF%-!-9Gv7THGxzTQY!#+PnUkA z4_Z&K8pj?M47bV>im)0AA4{pDZ*gz2zS2O`a%06sFUemK=gGlFwUH%ygz-zc?I!*?X3AQfUW#(0D+m&f)&(Mf67~1ufq3(ue+tpw$(n=5A5D z;9Xyg-0z`M58V}GuC zI`KpUQ9L}o0B>;1Mj=swdu8sgfKrYF5`tEpkPR?5YC=%L?u`eDi|UHh=DM73t>od} zJ+$g_793e6HBj)28XGYtP?EyaDFUo*t1aBmQyE?y#x5LN2)XjUcfuEm1oT0A6v7|t zZhYD=+^vN&7(P6=pD=|s6VQ=A@3VS)MN5&x=C z6dODwbs6|m(;Qsng_6|_g|L)|(Jf(;KFqzl!#+;0e#v}{Zrq7KTehmj#TatFewVW& ze(eCE#5^Rikl_pqN>HbCIK*TC*)#Z+si*+s$xE?Ytb{+zI#dXn4k5 z>F+r9RCpzSgmSWHwc&rQf5Z)aR2ZsKyH3e3OG_sPxfL2WO;j9%c+U9}4qg#xG01VP zS8VRNzzUdHYbqsDG+<%IdKIE*iDzaY#MjnpkOqDDR;@}eQPwMH+qz0rVl^y4KUFt!IBiP0*ruq8Iog1{rWZR ziklc;|FD9d0op#V%7n6E=|HJD_Fd!Aj3RnD@e<%KNiHC=y|)iWK`JpRrS@Cs`Vefn z181P{I1Wl$LXvf%xBq%{V$_Dzse0>F6pT2TVyr6G4LD9aF0O*-Y7I%x3+pWtfj*V& z2`7eu*E&L+BkIDHGizS(zGcBr@U$@!7j&XHXU9F{3nA*1nCWs^LZmLMx^GA6u$?Pk zx8xSHH*ORT^R+XDoSk6b*t?~iBY=q;^bRCN5iu!v;f;?HGWXp!>ks}d z1{du*Ag8KPjvj#ykdv>r;AR6+h^3xHgws37)2ZT>d1QH-`ySfTH^k^j8vRR;;vD3b zy5R2|&eLR(xi9|P8CV+SuK-9e+ED}wB#P5E!VXm4eAWlNIadU?1o$n-mh&qySr)$iu z#vdS6K%j*E1JN#(=sE7-VzXmd_R~pNXijh%>fTP_0T=xKR6wP;* z7|tKs!r%>tQL14Qu_&C_W1P>)adeXijh1)PtSA+$v_otv`tdyougR;%Yngm`VV3AQ z3A~K8Jb4kA$h}H7R|f-BXF3{aIINXXvEU_rRZv?pE-6q}pN=XZah%DHyekkJ>jN(& zM)4o2$;`Mw>#6f*ju!?nMg&9 z9>0!~@fFP`DwdU<-aiXfBgvl`Rw43ib7h;BhSJ$mldW(t+2)WYql$H8!JHhDJE}s? z;5gK_a{H78c&Ug4?P&M7EQsQA%JK?}m5RNhmz<)L*!MYbnIUR4RAU?Qa&$?};JfzV z8#AnEoh+UGk+wdzL@Un(g^4ye*9zSf*Xv~hri*H2SJ8J1%Vv_<5R+hK7vglN zQ1U?xu}o+mvLCt(0{?9=yoPjDSo*7v{|%-vPKLLVDcA#O#{!}9dEvf$!Sm+N4bV4~ z0tQ5cu*Q^!izx&rc*)j!ECSY!ei@@L4FYiFmbsxFL!g#U5t8Db@Vi~LkriVBr_+w3kEV!H%{c$5wxs8mJirBq#NfjNkql9+*Y5`Ni3~e5a2x#E4?L@8cF!umb>IK_7ZA1 z*a@xGH(MM%`Aqk4JDR|^O+Dh|w9IGQ8V!4YTYmaxK0aRS{)17sURBHFN34g&$?82k z{*cjAsIgu8X8a4N zhVPSE`+J>UjbF#lkzX_I5dF)=3x9B0G=4gM`ldc*2p>&r!+3mj z>$@|@uQNmE+2u5QXzVUcfG_VgmBnh{?I{O!4p{Wt9M0+VC8tvC4jz4@BUAzZ zj=)C)%-ga;L-JFITsJl=NOnyG0bxF-)1{vIz8)!8?V-(UBc_SiQ1Ln$aq7H{D}LGCum3@(m?*g+m4i$~jw$n?b!FD75o;(PrAx%7 z3R3TZ3~B|y=xXQnFg_x1V1P?3$cNwWis6t+UrsKOUfA&W1!n5QCiH3Vk3NBUwWC8L zT>)tl642Z7OoVbxL&=Ai*e*Tu^3!}hchxp1JnF~D3tIT??6fY&tiEU4OvD3NMht7J zPQ@oOYpf9OM;^t!?Do2x#DZYl$R_A+=oXtVglO*>T^Br+UaPgolR@9py8tL?9DLWv zX+%C$ZNh@F&WxNhBfe{KmUYQS;$-JfD~|+;{-X28 zlxU4_K2M)a+J4e$`NNZ5PoBKqXp&OBev)|m;PtwEL)L=vcKc7xRBG|B0pR;@M4pld zr=}m9M48Z^(dm{n*L+iawFj@9dUkwU@}O*Jn=E+|t}(dyEf2B{T2aedJS1mkxt}e? zvxqmCFQc>SlP<|NE!iBy9iI0|2Ceaw<5;~mW|N*<()0Liu|@py!@{2#G{_swu|@C? z6*gAg*4VnK_(O{03!g}$K>YW5r%Ei~q)d>}D&F6^=^gV82wxo)c_98{6*`cb$6erl z_f*#L6*eTf1WvY>OsUZ=Q>wAe8xiZ))hN8Ie~P=@++BN;)&(=%%$Ihxc`hdROiJ*5 z=^KJ+^ivUKhcEQc&zsZ4?d|>G;3s%iNmgIy^*>5aPka=b2l_d>H!-=t$}4tt@o8$U zzAB{GDe7x0iD^-hKHf^!bnCR(_DL?p%xwuT48Y|T`$S*)knumRrp4X+ysblbptmC$ zSx7kIU_;3$CB|RU*~L)31-;VKD?+jx#nNkmls;{?#fja{38KGP61D)aimI?YIH@;u zKqq&ZX?zMB2kH0Ya>V5n889=SHI8fxWh`F18J2rEne0Xl6;3Hm%$eLH#kJu z;Ru8A%(~(yb=y4x1t&(vVy>K2Y|FT5xZwKQv$$zT#&>*^R(`@+(@ zQ>YddTU3Q6f{K$WAc97ufEohJ6WEO{jONnSd)b&Ft$%Hl%lhLAlDK3~HB`))W>W6Z zK_!D;vizoObR8YhtiNiZZ$w8<@OW$XF?tB9fdJna=m>v zNq)p+wsi8Vthkifs`$Fl!8hWRGVMOY(WO`#m`Q+vN9kd5R8&pKpM(EqQZN)Upt^6I zS^ll9rH-!2k}mI!15}w$HwGPE0&XMxo^KT*8Fo~f1ymZ}j!iMltb-H?!0|_AEcyku zuD$l$*#CKtEDmgNcHLN~$P^Q&&C3o}w3Cn_!D<%vqE%aLRkY>WJ_Bpu7URk_V-7HVX!ha(d^u zikjFPuFdvsr%T=SbE3;g_!#@l1P+D%-UUdasvVqP5icPZLcNWE_OoqCfZ#s2Rrpst z`|a;eqvHnUg0%Rin%`SIyvYoWj;uS$C|s93s5=26-@ofm#)#DATEOlqgzT{=?k?GW z1dO3|)RA|c_f=@99TQwO4kkqf-ERJ*{TN_rY^@amMc`FDKRKWR z!aa0@7vysXIYuqm+e^F$!IHIv*{QoMDH{?jdEGb>#{|_7c_(74>Q)uJD(9JH4ugW>;Y&SloH`p#&;c`li^*vQ8aCx z1yMU4X`))Wi@K>Nvu4XN|0LKY=aR4^`sI>|s~P%hzv`Xykv{>#3qhPk%yD=KQ#=VT zXR@jEjPcpkqfd1sulMrl>7d~(IgQ8XxZ}L0mMeT(o60$K;8hu_tgK8ZzvnxOmZKQV z9Tk*&kW4%XkEtAL=Q;%cg_LJ3*CfK|_MmerZVZmIq3)*Y{495v}Ij~(|`c$!UfW!i8QQw>)x z3vW(yp;bX4|L&^&-K!o7zDrV9VH5*r5K9MHazs@Uaa$ZYj*|cz{w>_ULYJ6R-%&rD zhGPE8N#85Q6ms15W)r6^Z9nqYgex}NiKcbdxy9yE+Bv1s)9t&Z9$B5NST^= zopRnZ%9vkF0Ac3=q-+;71$kv9Pf?=_=f+zFTYUr$nV0|BG5-SF-1b(a#p)9Zfd!?> ziE^0s&3Sb7;z;(Hs4r*>NF(?Admm$H`0Ecd>cjGbb5|aDqbLV&sExRkDbALzD$&Oq zGf_kF6qBovB%pj?VNn3cBWYNVD{L{)4q!J{yHPk@LNehnPE&Ktq|@=uo~1r~hXNW1 zo-JXRN{8W=o|#LW3l1r^iCs9Pjl8DVHe5UhPTHDqqPjg~$d{QL)ZE&q5anXP7dq$k zfy~jzq-==SN^ZYv!j%duoqX8%npuv6Mg!ru#L}2zyFuP5B=rs=8x}NoyA;>{b?}L< zf0obamT{V<(4;*3+_>pk|(kXl21XeaQ+oH+dCwb?T5}4 z)YrMzpSVCQ_n2ICaY68H$2u*IO(HgE%k@@YfsLJDWa27F{+;VOpAwc(#CoFE!L;53 z&Vmpt?Z-SvO2u!XRG<%BdD(u+c4?iP&08I7ZbA1IGg}+P;)#CUDS5X5hm`q?iVTja zL?)CXUSz))n{58Sd1z836WSI$7h!AwtZ~x{m0E@2j*x>l-4Mm^CKLtb^btII`aCn1 zxk4d97<`*_Ik646_ihGZoOUnI!32Lo*{(KwKXQZEwdCU*<$KH4OJIOY?ip9=#^l_b{XB8kGyX|!}y$e%fdWBY(ZphA|8?+AUvP~pkmiaP6(=ZOy&A@^- zj;xpf#2r8fQjRh9BhyJaBKk?4lXtn^2;^xAN=Ic%arBqVi59yKyd4qXK-@oHB($AZ z%GHMV78^yF7pS_7m|8ZX&Xa*Xy>i1&q&+h$Eb~8LaF5)&1yPz*`@8xpj#+d)kt{nA zqsv|oBuPi7a;`{Q6J(Z4`cSoLMlC4#b&5%T2))w_B)Ji_}(g2+9DE_P*!(dB4{o3W2mgh9hYImV}}yG%_WI&h~&Qo_Z4ap`}eyQqo!5eaE7ml zq|V%dg36hu0Y}t@RpPdAV#<@T6Swv+2JG=23Dh%%@Lid=5<7(72jXz$kM_*3$=7xOKT=J ze%n7dKlUmc^*jvI1k#VMMh|g5?Djn`5Z3t*5@;bo1<>t{H(V@pp`I<;)Fa3@(lh>4 z^UoWB?edVU0p0>tT-k#dh(HFkWJElYl8wN1{on!bHa@jR2HRl$*hYtE%*^JQ=O3_i zTon2PzZum_v7^KS*n06J%2(Fjp^x$B+bWAp+ejLY&jU8AUDyZuB1p+IRzgeH`7tM@ zbVR(3_}etc6+DZ16ww^aMjtv))#~=0H%+dR#NG_soEjon1@)T6;$z+G)U8o9g_Pnbl>8`1Zl4xfcpCX;c75 zy(@CiwKp1t(p}#a%~-Mc0(YDBj75fRo16g(rO-a+-J!jV0BZ6il=_ zgqtfF3SFF^-65qhj#g+p>Ezn$b3u0{mc5~*@OidzDn*tXrno%qJk0+7L;BZ9;%-5= z13S3;PBDuX<6*pfn(EzLP4RC7er9&3>7nl8Znp4=zvu9jtCO2ck~lm_yCSjATuRc_ z!?K$UM<;h^*Ii}{_t@jvg=#d829zpd9biSZBZaVx;R%J0Q}c}% zFZoaH>mGNo7}(x##){e1?mQAG0SdP7rV|xq7Be=qyb9*#?c_dIzZZ99q193mb#x7g zTS1dv@Wn5}hcXYqLSwNAhSnrGSBRnrSI(1u#L`0wKce{(v;Nx7OIich02a>hQLLv|hfb zRqoT!KU(SDCZ*Khbcn#c1#1xZuAMs3W3RabZC@yI%JLUo+eSuCvOE1gLJi|KDfdB& z4F{@lSX^+Y1K|}NbvB{c>yF9wP&SJB2wpui3;yJ$=IhNa$nX? z*nW2(n3(7^dC_;OYwKiXa=Jly-PrNVzVuOeMh%dggFK?{@tgeJ+`uI3%2i(EA02q} z-0lXO-q|x<=Jt1{P-d9T2&j-rFco-qb)D-}JsZk!M*_$2nNiC4Uw4L(2mY1kH(x3r zEsCGbn@QSbOFOK8CNZ^~%VaEx8Jx9yU<=p?Vh}?3Nbyue0HYO+sOJj`v{%Zlx zlz+=pN&dI2hOMQ`Kd!%Z6}O}J84&zu^%-BApiOVSG|-H&R~?!uEp=u`H^j1ku`LWC z|9oVZU#|)lnwa_NGne!0io2f@@vy|-`ZPbi0?kf~H$V7VkKPVwSdRXJ?tcT+37Cm< za}OQVfS+%HycD#g8v`pqI-LwsSga|g^LA~#giReTDMJaJ`(*BMyhrW+I;o!dW-VFN*Y6+s-x z&f?u!8gFN_o4cbEsK2x?knoJt0O&rmZ@$$|-k*DzE7!dnS{JCA_u1zQ=&LwDigqf@8n7WqsggZ262`1+;DshImPNXmEdV(S-3;0auxo9A zUeg3JVz(Gg6;z73oywWAjx3r*-@L&ilye`-lpvkjGGU2=pr1Px1vRlcL@xdH&^c4O zQFcuzD~JPK3OGE;nt0K5hBd`nw?eAGC#)%y1`SJfNDAc`Qnemz9~NJM)-x{|<-ppd zb{zkA#g^4u2TPrbCs`c_`f1Fpvt#mrg5}H+RbWi*Yh{K4lqSos`fTns8qidU_=9w; za;T`piUA8BvJ9nc_){@8BET9`QD{wzW+{wnWJD_>K^;OnnkK7PH$IhC*K>L!b9XI)? zY7!tEYU=Un!_$ok6#*O6mc=6f-gr4~TX#6`Ea`!W!vpVl88m$Tu-gN}qS|THZ9RSc zA4hLrXWvY1-bgy!us&^E-}LFC672I;8BC0xUWs$zvZI&`^*q8KcEOF?Ww!}0WypEm+B!s${-{p>&N{<4!#FR?h!GEn_ zi(~5^E@&W`#;q=3Hdp1045Ay(zmfh4p@1jpy@_c`Ya(pkMujpEU@vl!+CcFyttxX; ztx*O7NZn8@Y?&yWI!g&B>upKYn^()S3C=evhdP2|PE2(ooz*hTD9B}yGgT#oxuR-Z zR3oFIR%fFQ*_iMNJj;-{mrIMg6hj&IS2_2kgjN0_aimNZiZmsp4<=wz7c+}n?h?n0 z0q!Ou?M%+x7w}7;Bbp)vH3O2N{wY@oAvrRlUP*X<^2h0yYM2skYRO_LRVY2!>bc$7r5fX zrk>uYg7JGgP;fnX{UhZWJJQ{zO~$MgMBCtx#xY--As&niK8q6NYN*yEQ*zF7OoO_b zo}uc5Q(#BTHuO}L#(fu2T}KE$99u5Bq?IU9ud)pGw*#Y^{qjX-!MNJ`@$$9k{lAq& zji6+xp#A07!~YGx%*-tR$uFh9{9;4szMuy4-axU+x-O*X5CzmKvIS}=OH%3Ln?UL| zG>iMt43WWVY54E6WR-d-(*!2jTWeZ0NBh|kCK`z8f<-RSLi zqTKU*_Fv}{x+&%8{Gxp4G`aK$Swb^t>7Su@Ynx><1xKF|osplD1Z$Hrj|U1HgI)dqWg1N@ew3gFjSfAs5{P>v`gbQ?<|=PAWS)xtyZ@zhUar2g=7M}H zWb_4dgl=Qqb@cYyOA8fnccLw-vRc~rkTjhb#t?M{sxX zX8{(x8`kZLk_v+5&N0xy zib1f5`Ib2mtrTsLSPG+FW)mBGhby+52RR(8YnJIuW|b@km1rhbxF^ue9dw(%(@XTV ze2Jl%%Lp9UO8dhT6Vg5p!K$xnG<*@XSV@vnJ@*O6PRxQD@vufam}#3NgD9YO@@sCL zHQ#dsJA$C+n$b=xTAC`!bokxq#rGNZU$2f19C7Ub(W43UmseE(TafjS4qI9y zXA_%$u&Y{WTJCTAR?i3JF_^^qH4wR*yxl%q+5(3)H*Gg!mO!g{NqP3eAHO| zd|lG(>u94T^S=Oh3x)z#w>D4ayr6?%R@1t?Uy^pxhu!P?cZ?`1@cv9iERyx-R zM27Atj00RqMX}CmfIZNj<^Wc^(vi$D1*@cJ-FsGtsyMidqt4{#hN2Z7p{?1HW-0|N z`lzDfFe0cdC^?rP?U`yVVbZ5V5`d%#3HPh(9AuzL?h)z72Ws?1jkAoZbDe;$Zc>=` zyJEJX31X?JSmmvNrYbBqAVnqaksVOcQs~#)fJwxs^sQ7a6*y_3lwRMyo7l}LVCSO8 zhybyqJB};i>iDQo9)~nUfv5~C;X%1g&H<-x9>OZu@3O)fCY!j3rdynS;!Eyf`!$E+jNO6kw zhCOMu5*im#fpv#rx&Wz~0Ra95yVJA?E-kohLDkXw!ylRb?*RG$GiyAPUf6>PRR0g& zp`bFZ=|31RF`uCS33vq^Wf|p$&UC)NK z8nYKil$7y@uuBOJg*yQBOlb6z`9j<;-a^jJJ!pVp!6sAjd*w+5`E)XwWrQ--Te~7@ zaz#F{Q;tHvh$JLE&Dw1X2Er2hSm05cCx{YlMtvmL0kI+~)^r5fqU9iSlJ&;g#gmy5 z?T`hjf)Ckws|$|eK<8Ga)p14kp|56PdTeE7@M)wEmB#sgZ0!_MsM7Pz!3TCP1bW0s+>sScS?|hWa=|-pu(D&f z{&6AgU_I()!2Nv9*$^%m<)#xlWUNF5!_HN|mKz~ujOBoJ8>z`Gj#n3bjq19cF@o2- zw?zaMVk~AO>@{MhdE?_1Nnynq99SzfEx@%Z3pOJ@nS1s%G1Tk;T@sba8uk()Ls9W` z=`?jItU$!t(>c`CYaos6i|-}aerlt1peLgCe%>gOs!pmdy3ZSA)^mQyoyf}g&-rlB zwO4H(*8FtQ{bI0oEr)}l@EC4n#Hd1L7+=jX|EuLiNmSH;y3(_2Q{|&4p8jkazjk2v z-9RH)!)mL&Nhm+J!NYX|AB+hRzzdJ#`*NXD$hObao|V1&6djxM<5sFrFsz)Vf@_aS z(c~Tvt>*2SIDSR-{znrOzwpVas6h!Q|zN=yKO2iQ>a|8fW4Q&ux#UtjZq0T1S8cBgxc$sfl~ zyhFxSZ>Py|kV22qEuFak?KdK-X(pw0&C<)ZY?eG;Nwwi*=&4c;a}ymxKEd^?Xkt7> zFJ*wEhW+vvBGJc%&(Mt$YAKGME>$~S18u9Srj_usyODGcHTB0gc?_@jihn?zSLL8; z)nv6Id-(zQ9U*_#G`jJpXFoqCqIuFlmepWtql^t3mGXcj_x=3-fer~nJ1P}2Vod$F zntB%%lBG|KT-KHmbQ`16z07b!-9nGqrTRDDj7p>heI>-~o2JL8eQ|w2{46;$hHuv^ z{tpGTCBO|kOuSVivn6es@01slxlO3XO2gEMhROc*w%5=qdmFEnU4sMr%M0M(LnUdk ziql1%r(xYs*OW=N{f22Ur44y7%_x>y1wj+w+Q{kF$3>8qOq{q5s-qfdMcdt4^Mwf& z(?FkNV4n)hbgWR!&J8!+4eqnJ+>Q>NrZLjN-3Ga(tt`)U{WA-kyzn(&YJ*1g%wF;n zEeoD@_Iw)RZXM5ec~6B3=Jaf6qiRj=|HIfjw27hwOqylewr$(CZQHhO+qP}ncGW4{ zocr}GdY<0&{DWL1A|oT-%)2k$RtEK6rr+FNm81y3IKUR+kF!ZyjVK-giKo5_m|3Xk zyD~j`HpIOfT-Sb3pE!)3tcky&B-)+CEuI(aLqxV~Uz_w9v88H`+1{vFdXP~O%^}h) z4)>gNEn%1(fFt z)R|+20yRLtE~B$cukxyY?+5p!#_pHDVU-$0{;D_bh+Hfp@!Z;Nib_3Hxm2 zN(U?%{@bePi1%(A_!Z(-F{H|&9|!QTd`8Fo&#?Q0-%KW?=1FuUi-CFGazI6V7@ubD zE9f&c|3#XWg(SF!ri)!PTS4M=3M-S!rM|hkcoyqyi6U#9E7z~cx$2+VlG?g>`ZqrB z%Wb#9+b8VM!t_F<%B(tkT<4Ha%^q9)aW|e#{9x6Vf!~kv)R{9IpDZ$Q?!mS#QXh8= zQG$jy2#H#Tc;MOX`Uq2O zjY7qq)C7P$x@Eu;2>?MBTnCe+ovHCTMG8|X*ZUO5R5M{3?*j2uCfuMjK~NPU!#<@k zJ}onHuIr+`&PgEhZrxRmSA1w}^8h>ncHwL>i6L4Y70c#%a39BckZ3h;%v0tefa{uQ z$QKUQqpUdwIqe_A<~&}FjskMdyM#Aw>h4ECW1+V6^p!D;K! z*FeAXWpP^VfOe zW}8$MEB1BJZmWGi1yzL=<0qz#y&@je-x`HT&+rrabQrmebYfgs=T+LCqpQ#02%dGZ z0_Q_$l zhzrx(U(Z3niG=C{#`KFb9cZY}zdifp! zGl|m%ZB9`GVJEKf%&OyH70pj>q!wRvUo-q|-4K4AvILtu^AO*7m-XWd@4r+xYw}rb zZYoyphh_pxK=-fi-4p+4f5>ucZ2;1U$-$~G)l&U-?T8n(Ze)ED<0p5>smkdAifIM3 zKNPxXf?0p4G~HcAfy%rMT~W#=vF5e&TEFwYu0fEU9{XI zj#uT5=`gh!n~dbSD`+FwG|9%cEwgD?ItVdFX6&Y9Hc|`Fujm1!?oG5mqGAI z1c@AXWDS8UxVOZljh)s&hKkh)Ck0dI?gO%X&UTh3*1V7?*yAOi&K0(oa z(fJ>KD9#IrPWW6PW((}D4FC}$84#un+F;q!`2ntzuSx~qYTU-Q}jnR|Co^&oq$t>H9IAWPc~X{`&B6>nYY zMNXAk{Fz~0ODxb))3kisLAC(jFONFS!<|3CgW~t8{5YdVIJ0lz%Jz!~Tq6dQ-?8L^ z-SjzJsq=@qf4uY>W4OVX8dsI?8l8B4>3IjUYifM_UtJs6u|lH)3x$_kz; zOy7r=CpVeBs#3@VuvbJ;PlRbv)j~1PmBg-RGB5}k;!LI-JQC)CD3G$;&4BFfCs>h) zkYO9)9JV*4inSmITE=#PjR06g7(i3vke?oHfo^04MN#oW7lBE~P*R1MKza<_nV~(8 z73r~7EkBS(R)(rM(16LmP~_YM9Yl=-yds@Fs6G-|6r|`VOCWY~Z3Fjw)iBKw_j3|D z4aPqwBgA<-BDo&ZG+_FWuZ1g0*iweyP?8k^MIt9Mab`FJ~b;fnKy zT_S8m{V;6?_IkC#hGn{jv9X^YQ5y@(5O5|8Y~(InUB5rW;lXB`TM^smhR24;R)$K~ zXggc2LMwGCPPitjS#mJWWyMK&f_NZR-W4Pt+v%psjaIf-dZTi3M5Ssa#MX-F zuFX_rhzc~4;YH|4dZ~L6qjZ5Kq;7-;nft|d3b>2 z_p~pa=rrrnGi}Qq?svWU8`kLeS$=vYLFO%J=T@FtBfiPhKe7dKgn72*(mL&3*>RYwSe%nF*00I^w9j@7Cta88lFQTN z9)~Kiw7^&=G^p|@&k~#Wec-uCD94PF&0xU%w;aF71M=%CgS|%FT=i&=8cLdFbi>*6QF$f7IqFLOQFmMEuu*LD-p1lAaP zCE>3l{4-(I+`Quq@ z0fuOH=s7NJGL%IsDYl2>X&x)a8oi`dCth6m-~W%Z@IRZ*Oan|EC_MmxO!)tg6t?+) zDQxEdH-%m6tLuai*(VSvx}kMP-;x#7UxR)oTj`fxszcV#I`8 z!XWRPunBz4`by!O^fJGDOrNN*-gc7_>l!%`bANyT*Z=+US^VSb#@pT9(bSH=uQN+e z`}24G>1Q@$Uw1QA*2XV)4e#IfXROctHT<^!H<>YQ=58@PE^Gfc|98f}>0ayn+Nb$8 zFM4&|ZKhuzmA99>;n|zB)o=6Z_x9wzU)%lCVu|1XHJY)RYz+@ftLf(UZ_9S`&Cc{| zjLyEd!OQ?+@=UUyfXhSx4VyU35` zN?iL@qu0($TSfKhT20y5PFvjuJ(c;)@c6p^zon(Ct@7&DU+{9BS`*0*-CgD^i%~LF z>)oHP%U*l)Z3(Hi{EWT6MQ_?`bdZ<*D$Sls`RAw~P?+>fGEuU33Wz5$$e?gchBXsy~;x z=ki4XQHt8urt_3EZ`#h8A3`g0l~(67H2vikNvb}#L_M%ne3gm&B1%O2Y3`Gn9|>YJ z^!m(Ymt~+0<)Ts2*6NMMLEHpru5l~9%MT* z&|$rcEQwMGsX$|Bb9xC(2LU}D^;iT5=&nB`538^rl#ZeQxw4YPQJ`(-aB(P>R(BIg z4&lBVhf$%EqPlrZhN4=m9wJH%xOn?{-=>*rjc`0aeub#=jy;#71XxQZPSVm-oVv4a z)Lm_{YJanTlb${CFQh%zc&*U?WrVH;=BY)KoA=U9-ll_^>$BF(6Rf7gR1$h^rHscVco|(YT>tmpY?E$`AguDXknWGh5gdC4#*)~Ehqa;;G0@=0A7yw>K z^jW{O9ARitn<%?j_<2?z3v^`1> zvAK!FZ4$xq6*m_uOMn0{R~RDYS$HEp!EN6L)A-a$i)sq{MFhZTi{hHxvMu2YX~ z8@G`JS3fdgjbf@cNA@<&LZY5f5hjuru^x6!#+?9bZz)OI$ed|&i)$(v)T2<7?v2(4 zax=PywnBf)rd9vd2qZC8q@{Z+`4ZIYoK_+sDJ_5&qH%#U=ogculnrO4V{?7rqK^KY zBa?x&akhzN4lO(J07C-%uS=p=Cq)!c)afj_eUKZv9n%nG3ph* zLWq!#h(jeP;4vdR6KTzHv5YO=sHwlkWbrl1DJ#i_qcqb26ziv+@M$R`9z{%sTFwy9DyuTy^ekhI8jCAtD}bE zNkZc;7~ydn@vD+%v$=31L*(=;_o~bfQeg#C;ZluvxJ*@eXW_{<7=o}Zk`#FoR%V|35|5Cc{IC+V7VZUfMh~MrIt3#!15Q~Joy<+;0isv`7>0EZPwLu_R7^l4cuxx05&6p9AXv~J?j6h-J$|Ilm_ncNr9qmY3y}^7@haqR^_p2E>mP;S z2o)Jsz=;UKK%ki<=K_CqQlvu54i@^c1{oA?Q-Ib{jAmEglMqpj7`>G8qq{)ZBYbOBTN=mHHgHm}H3u)l}4c(b{L+ zX@EwlNDyuf0a7(Gl;E7UZZ(d&Blbhje5|iVH$4yh<|Dba&JKu;Sh>?mRC4m zwFybIKU+&!BAE3PHb~}ANONTrzD2C=7zlHV zQwwvjRwfj7AI)SGPo`N?mmStM9qAU;{Jc*W6_!sC$bN8dqE6F~6hnT(kNC6Jbdol# zE)h=Q@Q}kHf>Q;s?~mC$b2xn+<+7@LgLrB;F_?+;du#C`WN}9uLkR#Pjt~ftl=r=k z7y~^rG(b5N;{DZ9mEEP9Ba|R@f};23XpzqWV7d@WaT)Z5zx+rSQuHEa?-^z|-4-=A zo~+NVp*^eXg8b^$Nn}S-QLhsqrMKugj)eTAp|dD8@TZ4gYd}bG<_;GoFh$=_Lj?8w z*b#|Ax6@Otd*cg!O<|U&om(x5{-DScIL?#b5I7GCVv{aRm!%@?LGMM*VML&PmQ7U4 zXhe}W(-;}d-v6EJM3t`*gHa?xmlEiGM!?Qtveb}ePg>!`+WNFm;;B{SF-kc(uUEfF zn~5k_0%O!hRC@0742R|lFxFv_kKBID)qfT>3zwPJ!12f}v&*iM@*|*&7|j$-=J{#A z+#n&h)F4^_({ZZs2XGw9^yD;`2~Z!>zhT%0j8sAV=IExQYHR2=hgj)Dj$i6d z#aC9n7C!LM%~R5pIH{E^pjaolaj%S`RZ=|0RX2%Q)Na!Qne})g!beac}cw@o2JvxpIN1It}c-nB=4-52_ra4=*YVauk=-RAxX9i zRtFk?4C2r%o{7(Cz<%<~MEjY~V?hW4__hSe3N~uztC}~|%m{P|Di8ZfGnj$oeUb5# zgaD4W*R2PX?B^94H6b6cqn$7kI1e5^{_3J?Crz6$Ue_xSX@joA1t*-eB?Q*93(l(* zl`e}T@vi^88zmG6Tgj(9Ju)eU47#X010kVCIp>0lPvzx=+BIk;dK}|hBr8`Q_Abx_puuC)yiR?Lz;7BOa3*czQl#v_@!P!1< z0I^>qX&2e53({4g=;5oKMc^amJ4J4dkYpn;y9!J+oi(^4JDE)B>H-@nD&!LyDf2)Q zBc`0a)ixW)aw4np9Vg_}3mPy&tUF({A(rG!3gs(oP4n==J#7d}M#6g86kQsMp!h=Q z2-){R6_f~EUz|R!VIxu1j#4aB;uU9ru6D33fQ~e{?MASIWMHyCwOCG;a*HAUU=syl z1lFG)vW>FhRU8}3j~T)Du}~n)bifITCkvEdH>l~u;*<_RcMQh`)@uFD@4gsR(6_FwK$wH-$2FEDp zJ^xC$i?Ds8$vbWhqK^Sv-)G)*X+VL{mq>eyu*`ZkPDzp_@9LAH68?VVK2&}ekO{pc zLr;&X2NKYDhU$Fink6%G6Xy*0`n?q-T&~CiTlOB&Wdk+M|Nli|6 z6JH;l177?t(!sT7ifXh&&@+&DRF|BE*b-ezcHE+qCPPgfBEC$pWG5NM&UPq^L`yd7 zPe(;E}<-%7^#AE z93eZ+gNb4s)N$v2ye9pa0uztXT-4uSzh*123~%T~3-@JidfD=GvTScA$^sn^)?H;#nj&#T@fdH%GP6VVL#Dvr)D~nX8hOxLTm^%G*5`QI9 zY=72hsfKzXYDg`;JSSLmjsq_Gy)abx8D2~fT$PV%O`wfQjU5$CzR_d}-AP1h8NFoH zRgfO&Xe)9CsfIAsPZ}-!x7rEc{p6QjB<)O0HXpm7sCg7INSz7g%_RPam9cO?&n0^g z>n8;0IlKhYgV- zavUETJS0?d=qJT`$eM{>1+u?*6Js?%Xdq6wv+Pyf?9VXpg+DGstEMm6W-A>dQSyXj zDn&CpMx<(H(#*pS4q=VHN;rw38j|i<&(kqmm6LB^>Fgj%jktW0NEiEO5op^khS zLq&vC9k0j2S2J*sye7^D3JLu3A^@?_Rb{nGAi-F?DNGl@x>)w3mcdd&HH2%?rc$s_ zlh28GlO0j=<=<(??6!-{YCq~ym$;cw(>-Pp5#1&BXen*WdG9?KE6EI&)T$JTV53xq zQF3g&Td{R&$0I(_W_M_fLDD|nEL#UF$ku{zv-9B*TY{H;+H}65fs`LlLJOtZe!o*{lL-9np+cKr;20xB!$sd9B>A1o zW%U)>zU-&f(CZ|`KnvFd^i-@9bg&_z7Hq6!B9Cx84;FeGb?+RSxY2)Z1PVp{dL^U);leZv=a7+;HEE^Z0bEza^J*kXDD#udD(d@t*A=DAI z8^%CoW!)d9q2Se2cYs=ofr*%|lx(><8AJZtJ(J{bCUB~QjRd_rNu5EF3oKB~D8Lve z5fuuAPZ=hcl-9`*Pq_nkLK(R}SK6n=-g-*{e$8pu=3M8y$xi>!uY`zNb-<*P*6Oip z^v8i=9925lbP%a{OjOGi(4)(N7-^k$;)R)2^I{5A8L%8+HFZdxab*Q^xs+L=W-ur^aZo3drow@wFNq09v>c%=P~9lIYr3Tr zectt>7UStV(~Z)&S1$fUECr)@H-tx-gD)PFoEB5CM#Ad&JzVlH%2v}c6fTkGM-J|K z%7UysT5GCYPIxT+ro^hWHJ-#D@~w|3k-ABp0zw23H}i-@$xuG6^${(<8A7Ue<+A;{ z1(|93E!wZQzQd#fI?>~qi*+@5Ks>(B%tyQFbQ>?O{pM{Bqwb%sy~ zs|~@zt+ig(D#x$TTV<&C5Ca2a;^5nPZyqPMBeF7=-3)+6vD`3ut=4m*7;SCI@4W`NZN z>^}Pr>}D)FzC#Q{Xq+(JE*_}2U4`4qVcD%xpwR0ge=vxDxQXdwnge-;$#J{4}g=H)z zr@(U;!9`qmcKo?k8}d-T2QRtYuMUn{hG0^j;L>T&eJnDfb(60iDCH-=@Cuvq-WC}4 zX6uuTfKWEh2t7rDs>pKUcpT)4#bl?Cc{Ea7M4t?c^JrZ8t{ll@&*RHt7+8{&>b1g> z0rL+v1S2`9APxCLt0bGM`?&oG0Z*#zsK!C_ZFQ~Muy5sN5#4>QRR;{S0D|K$knsy~Zx);r?yr}@`fdmTGLP#9h)pstS zNs~ZZ zuc5%?%vdWo0XfW*EueQpa`VE8Ibhaff#DGfmK=*H)Q$mgaTrAu^*qNiIrw%1g6oZ3 z5hoQo{VT^noq)sZejkO*edr$)RrIjrTA*W_!Ku%ySr6DJT^_6{#ZXb0_#BCKH$l!P z>wN6}(n1jlqw+~w9@VCt*Sw!fASAH~5=V0hOW3f4eJ9iI%epcWIX$1m((~&4uy1~` zuIT?>>0Gp$?3egJMNzX=lL#70>VNWcwP!RwD?W0v2l?#JdA{ik20!g$1yHGxLr9TSAt6( z+UBlCigqLmVu-sB2}ZRv0S>iJ!7S#(tJ4^5@mvqE&>JDz1CJ~gAp^ffTNvg z$v&T8uDa!R#C4U)uEWSSnXEWqHq@Wu^D1vAwcx`I+`fFMp_1k(^jiwGYz zCMaGbvdy!!!SU~x>jn7|Wr^n8Mw)ZNc{3ZsP1_pWEtgM?mcSq>tIZ^XD7fyLHd62$9) zaLvHiJ+65~y^2yfT50Fij$s=sfa6zhBS-UcW@0-){bEQN7>ttf0(mN|rei%`oDiKm z)0w06EdY_fn5?-bNG7uUCh*z77zTyQ)jXti1;>Eop0 zlkP0Td{`dc;MX?etxTYjF_QI0s)V{&UFlPIjp+H)7SIahT6PUi7_M%UiwZ3KZm0N0 zHl-y9)&wRPn)me*y7a)`$#BPe`ctr`#Cbts6>7!!1jS0KH(w>=fj#p50D#fIky-#MPP7*p29W)q^k0MA2_TR8&)_8?(jC_?4McLY{JUJ%m z;G8I0*QrPIxOrI^F+&o=+pN{4OM0XUZTe zX0#WC=&80DLR-4!k9-yl9{pFJ&a56}x0XepYDUC0(P>_igF%A)Nb)3wt>yQ%SGOsu z@!pRKcm*t-gFo?Qi+Mss+1igCdKMvvANfb2>wZaME!W>AGkR zaVY}|LyMcnDs25VW9@BuHh~FKu8qj?3nNxFWw;v*&%$H8u6+ zdts1Om(Z!jiRzGhAQi=z)akVocE&iiQ@LL17&bW||rt}5(s;Ic<_ z*}|mB%YzA)^!onx5iN{J#GVk#LA)A&pqI4<3X9jmC(p_;hZbU05gACdo=tX;5HRup z)f`6GTf6|aV(7Qci;QFBN{5(PPhFtSC`A#Sjr1$v8BMHK>J>&1Ak!#zmI}fD4vlmR zmm}I+4wJ~_8$#CY>Lmf&NR@QVY7Us2SW${v$RvghCMC9Ul!%hoNCOdOgd6QT$kG5= zJHQ&%i6MK8rr}3s5@_@UA+=C<0hgJ+`wMNg|gAC zv^nR@lhW5q1fC}~%I(D883_zG-aAAfVcH8uuIv5TCh2NeQK8;Q&4{SWLMSW!N}a4x zCLuaFTFU(1u5(MmSnZ;MDdV>hA+p?~$BVVKoy(FDMyQ&UZKFld1_v|3paQ|-6ziR_ zpLl&{vZIAeR&Rf-F=5A%H8xgsX9%b4e00lSHr1O$-vxLe`NF}crr7-0APwb-&=mwQ z{U<=7X9cCAK!z!2^2iayQE_r-)~NCfwj&lpu}1!HJyKB@kaMuJ%i{*=h#0vpEE9n{ zEuK1heM_E~QHl`fHZg(V}Izq@2J@ZyE$0j2fc6rkAI11j&^1zIlOMnKWc7*Yd^q*u~(L zBSeIZ+-I0NaqDH{9K?iB{}_m&A{|YT$XwZXM1XvTW#$M%PjeX@AFkoG!plQ<{J zlYi+U&}W4+B9AsNN8!lb$TajVmJ38zx_>x8MEM;kk4J0UbLJWk9Sor+3vpEkT0L0> z3NQ$eGoreP{NfOtR^FfhC`#N9Eh7sQuaihf2uBKhV#N9(VCE?#n4NS2JH?bu) zW&N7s1Ycq$^u~8Fve6P&SwxkKJRO<@!?tWea+fcmt5Onhsqh*d_7Nnk_Gzfy0Y;}~ zqTT(f@0Zsy8Ii{zVdUwax6X42*Kjhi*grfUIS8~f4VXsTgteQy81Kojexd|WJLetoH13QjV*#!}_0`tcCdb zva3;t=_Fe2m?;ZsH7Z%}g}Q~tMq5d#y5gtK3gl7)Z=|qf7h!p`qSKi|2#PpJgfD?S zmLr_UhAw*eezEh*5#G1f{G5r|Ni?TJ!wfLE%`yghu%okGQ<4> z;8Zy4ha$WWO+v^F?WTt7n_-wHT7cW60j*VeEL6?a9#8DisS;6>c*Cxv1=|{dKUzy9 zx13RhvB9t4CSt^Q&UGMGkm47%oEBz|9~Ii0POHVG(r%4CkD&$j!$}?6vrkuie*bUC z@t{b!rLQ1SN_w$2xKc60=)f)T1MU>=dL&L{uNlFHIrd_)*nNJjY*2KIcY3M_rqA74l;QC&;LDK^x9qfz8AplzQC?s>D{jvs?Dm| zv=5?iMJm_0M5OUP{T>1ZZt==9Cc=nWae@iVAD_0GU|yu7CDD#K*?`}zBO*yoI7_NW zz~%a_o1=e&gN~8PtYg?+!Pn~QcJ8YC9`frDfx3tf7mJDeoL`HCTY%>C^p%0_C$@WX zpas51pv~VK^e@5id(Ytj&yvbO$oaz=>R-u2pP@E&KF1?TE>N6z1sRrEH6QZ z=PMF+`?M1Nn9-Xs3b^pxkI^N5KAUz}JXpHS=wvEO)nGGi;QF3dOS1$@PpDA2_qA}lSD49qWlme$A%&x>dnPYH^Q%Y$9Q{NkvFYw{@HY|Fhe~* z&efU1B6kp3qoWTVo>LP!ICsw}h&PePKoMP>3qMnum@5KM+RV8+{MxECt}rzY$pdqE zCk2VraoaD*E{+jpsv1LOk%v=$mTyE>29cIMW={T1gyZn}bI{0y-z(S}BS5bY|M)`v z35o{_4gBG;lyE!Cev2$^0oYq#J-$TmlP{*WVERa6C8CsdColA*Hwr1_;rbUAvm~K9 zj=EpUUOR*suqYlIUovV^kqFz`qWR*Rv^S?G0TUePI>KCA!qLfDXUJ#+8F3Eh2b?cy zZ5~>}Ihm9|EV6@NUMQyx@tLe6vj=m0`f76}KEzQ5N-JPv} zN5>~~Jq-Kj{n{SB`4ZflyX%|5&oi^P#h!mNdULb-{dhFHI-{rSla;l(PiNi^|GNCO z+1fjJnSb`i?EU8u`0wBP>+k~k?(8R{=KkHi+1oov z2rd8Lz<|8P_@}Gs>Uev|yhvYRYMp(ajcQKZI6Uu;%=@^{8hu=V-5zFqGxzkni+ptZ zGj-=JBz!+FcK?ntS`1(Gw8H*x4_8NXd;Y!My`A~8AQ7!#1wZ!wzv@zA2&>tC{~m}d z1V772c=YvjW*kypHeD1sYyN#7l2w87KCkQ_IF;F%?al7Z)8X&-O%V7cx;K3O8IxBh*xT;~vxhS$-0cV;n1Da8CU5R~0)%%sr}{X%HdCW8?_GNA58 ze7n85{X?M?8#?Su7>5xs>MBhZ9Wy+d&$;Do(aa?GvlUo$0x z`J=t@6N`GgTS4!Z$>C7bhztMynfvG6>nsFTZ|MPD9X-DuV!L5vkKlsNKZ$Sl{XR?)J6jjAa|{=ug%0?s;c1;8AXUgeXRmWxXe4Cz0Mx8;&1tzj19{KK1Knyu{P7 znQtOD_GZr;qucvuGZ9kTASXJGPQ}y|c!Hk(SyOKc_n2Vf$8WGJ-NVpt4|mXE3BkIrS~8ZNS-@L`V-`i*P`aq04=rbO4ogBdgMPpgHR{&LrF z34XBs8rKYS=DB2?RxBwAe)HooNFNWbaeg3oy*`ZRL5u{a8t{Ek-^?o;tebgVe&|d5 zpS2im7x~94Jo+gG`gCj0VL%@fyTKL6_AH)F|K?>QG;8qZl3K*pr#H2YkHm(g`wyefQ1tb}Jd_Ib&`&ua4Qp5<4N%)fC`%hCnAb+k)Or(w^n8_(G zPriavJ-XgycIyo9W*lM$9>|@ z6Tc~jbns(s<^2y^hu9HsHcvZ$pvUTdgt+gKV(sI;L|=Uu=mS45qp$n?;r46i>^iS| zozX8>JZl$y4%mA$il%EEuWB9j?4Gr+E|YOWA&f{xtmhxe=A89zCS)_?hzatTU5ITG zFz9N;XepT{8<+Um%OoJb^XTWF zta5x2%G;NViPIC7+$bdGPWRex>Dk~72l)m`1;veGB5)6(&HtJ%zINyLec!&nd3P8 zsatuvq=w0o3I08Ez{9Q6Ee%Ez^W1QK3`XvHm{x= z&Fv3O6>f5jfasBHKX^@}QxYIaZsWK?U^~^#huv*^-eZ7#fcMrsqpw}Ddy+e{%{+^o zEbY~7F5O#N>QO|^0SuOY=S5o2@*iqNLiq{vg?PlJ)Rhi* zT#65>BJ{Fa=^c|N41+fajSEwiLaTVU!ZIbv@ngA45bV`>c3GFO0| z*-@bk$LtN+DJL!NT(gDW<*|pSha9J`9@k~recFnmKl%S3=r7nYvS8W&s`0A-b$I@- zRbnq2OQZkk#@i+j{@0C%3A^)z+G|3MlczIDo6{)UP{hk+Usyh|Plw(cygmGn+;nc(Z|UK0+d`~fW6kM zDlC^f>QG5*G4ftDDYgAG!Q6#J6Y9l_Pjglo#L(Dpd6hl<7(o4i0( z>mohJ%|}l9Y~%vDWz?KSZk#X7<7M}ySRU1JS%Dm7WV1HM*B`f_uz&^%*WwQS(VBh$E1NKL? zq@A}r()Nzk3z{NzOD)d!GP#vkdzEa+%wlOiqMVjAg-}cihr{UvH5dEy?{EM}BqrSfNW&d;|UWAFv-QB0h%Quh2yWXkt z)u!vKH;ZMMKi_G4cGf-`S5&Jb8g{U*+|Fxx)Uwf$$F%1=;BtX_NBddG=A!d*G9#IWu2*?daLwWQf+6y^0Gcl6-&#_8w70I z!#ptPKXfCO_1Lji97PC%ZU5BR?d_6WjrC+owP@XBb(fqf1&Gt^oyXu-r-H4tlJTKe zM|6gFh}Js4HxgU$ONp`S)6K|bspY4TlnL%IkOB#F#(-ejTGY_FC7o3Mbp=U2uBp%? zl`m=`*8W(WiruL;W=~~MLw`+H*%`+5a3m>;LtV`A-^lj;$?heTNoHah38QJQZ5soI z4u!StwU#%g$&fyFeLiWN)`TWoz5$DZ(=V1KzEmcK#!Ihu#t@wDWB4;LM&q8L!o5|U zR@(V(9kl12vADf;J?zPGC4uj1H~_{5Hd*$9di&jE#Dz!J`UEwoT9+1s6)&r2qEDr) zG1sz%l5xXcQ)xKHx#n71s~Sf!uQXX3R2_(E;Zee2S*i{`04&47kg5oRjX`lZhXT;B zmkr%E@HG`zaZqOusM~{yp-)5a2o@tlM$s)k&qpvCfJ5%b^v87; z!V*`(!`4V6$R@6I`!s>T_bO|(Y4JfVvPgF&p-t+jLm=uaV*P!6DN(Y8wtsq|DFfy-Cc51iW|KX zm=uGF*ud=2u6N#@F?nep1TUdeYO*tJT}KE;Jrx3sD!~Y2$9I|NKxK{#1GduqhR8@Y zwb7dxz{ol{6)}XN&ny?>$~7Sgh8K@S!x^K9}(S72@;bIXIT_Y3$K8OnPd(93oEB%qhl7Is{^R2 z45ooVmEOSMOMJ`j<;`A*2n-vJ3U0V#Kw2#V-ts+a|uWBl}erZyVH5_3Jm% zv(j%G@>h`Y9k7{rd;;({VtGCpsBBE+!6(5dQ_rIqyQ_5s zyQ>unxWKLU6rmZsyJnMgm=hJfT!lgPy+I%@END`3#3 z`R#ntz|B$7Hyg`V#l2$NQ=$MwoD~KIAq=h#s*h}*^|(LSF$|zz*I2tN1X%WW^%a>0 zX8fi#vq}t2iYh4VjyS3vCyl=x zQ#~wW{z+GxtE5(buqi6wP4mq`$J@8Dfo`)kvk)f!7I0P`cq->1l<4%PutVT7Z97=w z_WkQR3L*%u8Kbxyx-IT_&`t<@gkTU{cXNVNjoU?2ODkK|==|`kMsU&V`sHPSZ-}EJrauY+D^DB#8umUK8X;fi&O8WZdS18Mm=&**Zf;%Mh8&q4SxB(Ne71DV(SnZM3E zFaRI@YnX$#;MtIY@FK89O*&^fX}RP|-8VA%*-wR0vPXhP5R6>O3moHQnVlyXVqts8 zhK$uyZCcN=#v@~r;bCc(3|bH{pn9lHR&{?hqN^aD?_c+!rQ!#icCX}HaC<^}Pwk9m zU6nX?>;QY%hVo+FW0hW^Yhz$p|GwyW=Yz3HYqbG|#yT%FzyHkAw%3 z5B#immZU`Rq+kz!U-i&YerqZ6>%C1fX=uFeG0SQ&o$)vNlVCiv#lfYr%LE`9g0~I?MUf-;Y)q)nxmdtSY1Jl3z;KC`ESxC8fUAcd>Zs55WB9b0VShN z;U&w=zxGHHk{CfTHwr+GL8mf0(w#H$^vDIq2zS?O|HQ-Cl@&nZT9rJbAyAmXn5po| zKK|s>#ML~$O25x9rRapRp|v_49RKwFYcmKIN5~1!jC-HaFjGTt&Da}hIXs8HKC!lm zY4rnC@9BKu7Yge~=#Q1XG{p?*b>v+0)!VDx*JY51u#T-48zbSzvI<<1eiaC^o}#K= zxDipwm)J`L$snTb?M3Wyilx%vq`D}*ZKjg&#*p5$Erv7o>2@i;5MgVE;72MPBVHK2 zsgoo8CaHlsg6_k~ykBk1?`rbKpcMV~k*^lL%1iO^y<|td@^tuJZEV)C(6R%2^D&}K zn{xkQB{HywSL*+r7fHu4VSGQbKsi?b2A57^`SzzxlW)|Cp&dGN^p%xnO4v2EMSFBj z&<7}=`2(MCrk*)-^yci{;H?w(=Nqq%*OkQd!iW-o|%H_PMQ+Htr)r8+{CUlK9;7n`*pE@z{${;$IWu_)C$n9teR z(+9*#Y4hx+s5SwErcUlSpl~@jTg)uUzSXfeH5}wJ=~|&8R01!Pc4TVWbZY67xF!#6UTNM^udwZ0b8Rp_ZE^y@kGqT4iGDwX;=85~;gdOt zl&gE!zQlGnYv&__o>nQJ4;YcH8M!>u-Tle7oHJ;tF?1&rRx*8%xl=Y|_Xck~Z{XiI zCNmfTCe61BZ-D_WZSMl9dpIp&MWI1M!KCWl7!^YmoFI8Ub-DrPeC>pb-Gd4ClF!vPBXxHm`*Gj`*(di`fXTM zhq}9+K|8Sg;X4Vz(sk$GT9Seg9uw43T^hGa&t5O^PEa*(H)WtNV-~Dvgj;|T7&T2* z8!cT06zeg(*yLhW-W6{wYLAnW@)U@;Ipo|Ddh7-1!4GG#AkjC7#TSIEHN)-UZrx(J!vq~NG)?}9Ln6F9D0DOoTJwCm^H(T zd39W0?vN9(sS0KrEv3#Z1;;%Jpr2Y?Exj$uN3hY8ef}^YD&H`^KIs-mNuRa8WnqpTEDcng3!oq zawMZ6c}i;Ski8S&S7l@fjm;bJ=6BkqS!cVkmL9G=r+yxmn0tB+w1N7Sh4z9@LawJm zqH5Jo?pRW#`S{*h*|;l^&vmtcab9~1_i;2%ellyJsJtuNO zgqruR$2|#t@I4Oe-@C$&4Z=&MUIgYmVK4C}P%87q*;{oDrmEt41Dery0DfZpr7YvL zvi&U}Kz;QDd)c^ht--I43}olB;@{@Lp|{b@i|sVm_2;(bXY*GG*MYhzbNw|KUhyCU zHtXf<;c3#@GTPHMbeC4ydpLy(Sl=*)+~wUL;G>_?%v=~AqrZ=~!24Y@C@tyf9ohr2 z4Tu_)YM_w)UBC3f;9l*47h2nCaS`-TWRsdYmTS-rrZri3U)s>>#a8e=p`f1Po)s>p z`6%jnQ8)xE6dhxpg<1bi$m#Im>~9G(E-L}8d;+RXUrKR&i9 z&LDsU2a{z}#%A%n_U;Q+X9>%<2mAXXzTreS*6x*9xs{i(=waVGV_d4OpEoOuOtrs0 zcxON6QiVHT?-yKuA7z^O7T-)ZPA4*{yk2MYh`uFvmWEH=n{0F!)=xXiX&M@V|Dl|Z zERYppe?G6&y68K+4IYi+tEG!hthdp>Cg}LY-rMT|T|e~8?SwP*i=j|nN2)h6T@#tZ#_eT~P%!6>lTIlc#nY)YqkC&4X=`(-ZFQ1rmRnYLCh;}W z=F!vTDjiIJkj%Mj)HWJ7506Ao0P%Dcq9q~u!454&HTCd%J=PY>z#;+D zhFBT%i{|-w8zeERFS4k1S*g(!OdJ*q#m*7A0KC6FuE^dc+%tUNVPYT5w1h!c(20dYm@(1RLP(Q_J?#X1%tFGBXBSDS)#-j)|wwo9{FCq)s=b6+A*Heg& zfW3GhK-aEudPP{X=h(#)#aT=sC3#FQOkArb%n5vAv9dN=pp|932eM=+wy)wb>S58J zZQq$a7d)0~FCi?cow=sJX5|CIo>1=EQlrbosUgBlvjB!it9iPhKn<(Gg4l`uN~2lQ z{Flyh2y+u5UA-XgxcYH=K!aik;h&5Ip)DN3q%eC2^ADBo@=;0_Fq^4g<4QzLajxJc z_(j(7tkPb8&PjuN-3(*t9{%Va%3R;WE1*V~H=qJoFc8FKzd9%Be=W_y8kAX z68#KnI5g{6JD;n->R1DUv-{;_rV$;dXDvYly<{V~Ysa#G`nVk8DD$z$sk%_rYmh}V zyqt*@hHr4&m~=Vp{6w-Vz^;RBRd(I;m_nqSyjE$nf6ZKWGUe6E!y1N@vend@8$Ca>dB0spNF^>#=P&Q2oZo+;JchEn+8`pAtXRYTO^BiP)kp*M zXGP{5Azqd1B5R^E`|dLin!wB$RgVM*hm4|^)5H)3O?Ap zW^im)%Fr%#d>}6EZ-hxk8jjK~5_tZL7#464Et%{sZtEN~%f85<7^8 zn!?}xWxbt35yM)^x0VCM z%-SJ!GwKY)@aF`FrwF~t>C({v(is1mcH5M+QAxQBKFiz2+68spvPM8;oHfq^SL0a+rG zGyr(c653Jskb{c&cS3kES6S5-(AMyjze-+5XF-#cL`}O};`-7audeN?vCG)$cvfM? zqn!kuq`O(E*aTdQ{;2XWeWAj(9-x)tEFWG=s#P?HPKVgj$G19O^(Fjb;r{SZh}emH zO69T4sqR_u6@*i+vruWzO+SI(7Lz%G0o=WNTqHFbdJT}k3W40CLGvH+w`cPih$ZqY zfmS%?A~W<+mt2EDP%tVGV)_bRhK?ttjivfJ0ybX@^eUz#XU^!|oWz039X#rwVtb#O z0c&hl4hj67frSa2Me0{NAq44Me#rRrlpQ->w$}zsp3@)Oj@bQ15rit<+Xi04PU$id zCId(`YQx#JA10JB+AJu1fPB)DX9Gf~-@3UJB#va8T*bk(m0T=U{J3!v^zC5+)mf>m*DOoJ%)PF>M3K+ zfiGY{>3PyP{CyM>Zumc8+$oeu@?qg83AKun#FIuEVSsk59vmd2^rX}XyiEEzOmcIv zRbLfB>jcHviZL<}iG$f)NqwcJF}N!>HT4)v#2$-^cFN^+|#}4QJXYQSCIJ zHZmmM7PQ*eXuydj_8o97TI|cZi6cYsfuH@KMdaWbJz-hL4z07)%}(4S;o^Cs&WYEJ zal7{SXsF9PW42{vOFrjERv=sH01KSd$7v+tH%2mY2+COEZ~$Xm>M=6Gr)}m6V-P}w z*r2Fd@3oIZ|ID>#4nhdA!5!1)*u8ZRH zcrl#RK2ej(Zwu~85;J8c!ApAx9xFgW>}M2gE$q!z-T~VAAZA1mJ@`<4kQ=)&QHJqd zZ+mKkp!vn>i9DyIIQO0S)!ZDji%sS=nDe0%>lT=1-$s^4>qHVVQI&)Zgop?Z8j5Ts z!LE~tl-XPZ0v2ClPimk zB@h^W10z(gBOY^QF{E~URz9P#XL(n4P{6c)Acp~n0|OlXUZOMwB8ujZYCGTTVn{y#3uc{5N0 zP1Px7jA;EhgdmXTVwA^&ML?z9zr(dBKS}{1P&)zvik2b!wf@<6s(Gqc^PHhSEk4YP zvA@esAu&IIP(*PExss``_QMHWi}dCR(Hv$q{4Y0eL1hm)(;AN}GPvnCQ4qP{vOuJk`L+ZSS81PgwVLLV5}r4N`FPNI~8Go8)z@AJx&3eAk-+ z5k^9wFrH+#Av=uY6U8qQyM6NtUAL?UK{v4hyx91_X)%$XsyWQ%u}$mktRC?UtOMBw zQ$4!utr#DkcH55@Xc(iT#&Jf_9^=@sZeR-TeV=`b!v-K&V2r;I)RR^7YR5jaHI{wt zKVdKWt4ndyf$HQUV%f$dQB|edh8IQvs_5X=Fg>ANT(xN0c0vNT@}_&8RHjd**Av#Z zIW>m;kzJcz?>T_VhC3-rb|19YpX#N|vdJBD{qX8hi}mD` z$Le*JuMl2Z)Qjlt;g{j#X^}z zrh;b`d^S2%I>{~cUa17Ms+r^f^|*~ol4CWe9r8%vLEe-6{sO5HUY;xrMHpynrIiDN zi}O_}Z(6LQ3PyCKtRu?Ac6DMNqEPcEg|szhQCb@pf&Gpbt_35Ck-=+@ak}LkyAs=2 zqP-a3YtyD#z-DGEyA6iJ)stDK&qRX%&`cYdT<99`-7x}lDDtmfum`;J;TAyq02C&G zq{#1-?{y!n zjIcSaNG)v1(LBLt;pSD)zFTad$EZbe3fzrbU)UJ3ZEyN*615$6u%GlScV@WfO~l{xAoeA4>E z349WI!gE@&YCk+j1o~i6t~;Wtj>i;D*ib-73Ytd!=^^BLLO88X3UHcqz;-tNK|eF5 z3Cvh0L0T6VMTrvkM@ueslbA$i|-le)^FXNKQYD+_O+1_5ZBBwSpQ2!LJlb8rs$Fm z2(Vv5rC_wyty#}Ls-(fNNk{dDVk3CdM^hP-pWi8Y4GpjiFWgdT5!8r)F1uB47mxub zYVp=`1m|LM4E&?1mitB){;vNs_-u*7d>UGTyZIP3;_Ra`Gj(ok7x&NaiB;s5K_lmb zj@vDxBPKKthW)O^+ae_-Xlo%>XCIm79mqpp=l5NjSyP^+oy!=W^x9Qv>UOj9AfAI< z`~9ci{PbL)7l2o6LCI zoW<^5^9SY8ilP^>=dllahvAo50!PxB@-xkTPIuy7*0)2 z4=)A>>7TEnjZ{1HSrtKv!3|1N=~niLj9D3XiWv02N@nddRI)YI654`*W07C_=CT#Z z$|@UKMW!}{-yHX;mLrZ4xtrS;3d7^pwY&l=5I#IfScMr0DHpP1Y92RwxbK-&wQ{N0 zTLbZlI)vj9n;vVxcqP_ArjN`M#@GC^K#sOBJl#9@fOq~u{WCCUnd|)|;(gg9@f4;7 zlh^ZI*I&k2N{o=J`6%*Tgv8E`%Q*Usl;MB1Wvdj+ss(7lM{D5woJ0&c@*$`Rr}vV5 zdQYqIQdL~)|Mc!2tsvO;ceed=E8K6OHMx(yJ*!H~T29g3cVMV;Z1mJ6(W3jwQwJk` zhqyT=&=mFc3B`m%bfbhciPNT>W-=_2SM62SiDI)DC4cN9juau=BnTFgth zMTlYr+fGXYMrgqz}j$vh*tyeY`*pp09A;lNV?e?fuD&Rz~%D%?8r^7zh zvxi&m{Nfr2$@^<*-`q<~n!qIFNuZ6!BjCoH>?+Sd4XpiRlz!?f_&7GklS-HGmd;+8 zOGv;3WhKyN)T|@h^d%Bgc~Jd^dw~D2@2DXMO%roR*}QLVs!pxPtp!QlFKJ<1kZ$`X z6zDVl2Pe1Bb{g`pg_<)D*VlFIC9APGeRY&mjTLb&a%kTTmrU{dgc~c?zqrxmuN%>K z&Tb68DWk4e!WsIDc~2KMCzF7F3(?hkaa$4%;DGC|EoQY`phC8ckU zZzBXb)OUs)9^y!_QXRgFy91)I*qR$7Z@%we!Nb0rgR#(GM@rlZN`yZoz?R`G+5V7$C!EkgOU!;ZDy`8~vu zatkFQBiz5)a=0&iNfI~2M}8wk{J3QeIgZxwbGZYJFmy|kvc1T)bV7Rppc2o1c?1~m zIx_rOdNt*7rU!XHC&&@-O&ogVY?HGirh(fbiToY2i*itB=kwsi7xGWAJaWcei~w5( zFPwL)!T6JkJCm$*c_Via1K$XZ33o6Cz&am|Bd+$z;Z@l4+k9zx^t*?PD=_rN+8JVt zJY<@TB(tCVJR@*<&!JNnczN+a-0|DFyVRIDSUWikdCW7pJ7D*JH<$5XC8AsiFG_tO zV#Mtv{+8ywWo{!gH@&-&i#v%TgO9!wbHk!ws_l4B*tM<-B-g0n>XN_6@<3c^Y`t zaB0ZR_Vk;warZn$v5VN|8d*`A|A&f^NTZ<_gd#xNioqMkJ8&=JB-<_A;&m@NiM^8% z{ONtM<5_*zZ44lP{|c`RgTqGP3E_}nz85lOj1ahQ3V%V!^2Sb0{aO?I7W1*^%T8?A ziyKmB8hQQTEG{v<1AX7O!`#{Ao`TnW1nmO0IhKQLHtrWyAf^*@WbAml8}wLqJvjU} zciA^$cZWhjlz48M#@`-0RzvvklfAZEoFX&j;R#ze{rX+p8gsY$`s^r}E;g+Y7VN(7 z#OREig*&hb{`)PON$d0c=Rb@z9s7@R-~SNsbJ+hZvj5j)+v`kMBw%JakyYja0VJ==%5*?}6WVDdoQl2vHd$Ve$1?JRl}pLdHRU;ZT0z(JlI+4$fWxFZRk~7 zy+o(>K4klp`@VdNHk0!uTBc^>`}pj#a`yA7^U!WF>kx! zQ03cl(f-vUmuoZNa`kz&utVkSZ2CFZR|N2|^)l+1R&IA}53<*3Os=*%?c93Io>TAe z?+U@wL~7hPw+W4IqLIOhD%W0PE51_2oN#WVTG!gxw%C~SxZu=TY~o6@s9J>EbWJ5h z;u7s4KqUn|c*0u1)LVS_?(w(x#(|q{rpeyn(sN?Z*5Yi%J}suy(b5>Ev;m~(9XHQl z>732pyfoz>KzchKdZ;MRVWvP+6NH^%>f6N&V2ACmY3j*B_b_Q~h~nL@{h9UdUC+K7 zCIsR8d6WaD!ufcR`T+fzhOIo;Ot^`GJZr^E>CsJ#bS*4~Jw z`?R+yap|)JH_pS3xP4Zc?Pa%vRyHU7TAUsjr&_V1X8TSyiO8cO zOxbf^W6ZF^`>K_`Wxxe2WZOi@iT3`{XCEiD_t8ocz3J*`SV|f~mZ=;Wm`>@)M;uxR z433uRqwX8Bf%46E2;ZlX$IYy#{dFM;{QK?Z^p#;p^dMP)L}hikRTBF$FpcA+IK!3< zD9RUn!H+)*kE^0P3L>>WY8cqYdPD9k3;Q|n%EbZ|J+YI{%XFff_Ol)=l)se@c$ja7 zTM@#znu2mKssMHu>ahtU@(#0lw?$a%R&QO0_Z|0}wX|Dp+7s#7O5@e*z(Y?`$Z94@ z!YG23n66%j@;ZTrjJCS*O?%lJ1%cxnekDcvH=CcJXt{p&q?~blRc$Lk9I;}X(7kUd zTvDQ{pWtyC>9Z5}q*MRBQN=sY;)A@^kDkqzx(M0Om&{8mvkT@`EP#*z zpNw?dY&+pEPU84_F+4c;hX{{aQ?C?}nBu7byzpIOdd^sN@u5oEdR99vGC6F60vc85|$yC`e&WN36{--`Kttar1@k-Rs6+PIl~Fy_us z?j}0o%Dgc4I3|ZquqG>9Y(;}*U>pmJbz}vnzoP8A9o>6i` zfaXb_ketvqqrX|8j!gk&qg(ebY6|&IoxftVg62uJ{~R~lUxBG&kx;ay4B!vn81|~! zqkX|AMu~4Le@x;}3QFWP7m{hCnM0KyRjZ5ERK;`dzHzo?kJspCGE5KGRex= zj8tJ^c}DnEm?v#F1wLEgC=`p4n42q)WB`F)BsQK60w3ui01#eC*IGJM!+dNCE=G~4 z&`fF*<7UC3!VC-^ZFE8+w$XDbrPV=WuS1e4i>waUH?g96U>$7B91&>Kk=py(G}dd~V*zk5s=v(L~=uPn6j$i-~VprL(=vCJzSpRM-y# zgCG3G2u44_MLQzbn;VHpBABF9DOGM?7vyU!qoict2{3Mlce7M(YNsaPe$K+5NE~Y6 zKq=~%E0I+L%KXUrxB^Z30#e8*$o3Dc9UC7 zezO|qRpS+%)~Uv8nn!m$D6kQj93ws!kcS9-J{gT-BU&)D{lf!IRaTg@!m?+|)IpdF zULpI=uZH%{Rnjm=Pom4$Azm-UD^97Itu(hbi}7K^>lkWzpe;j(LLONV)`0)moH!P^ zv;W-rLyU2Eq|XwN2lUG?Tw|et$X!6gVkn{=1AJv%s1H z_@y{%f>fuZTf-z6MLwqf8oSc+>r>Fz7)jbL2#2#kkkn|6IRp-umD$jyHC7_1;mwsp zBdr-$@W%OzI<{yW$4_3xlD zf(6bXB&&Iadn}b_b+l^U+gkdPRjr!sG%s|UM z$%28viwnx0awY4p!WLd$1rnA#VZqh0S?%wOKkY=Y4zlMe4{byq0pH;a=a51;|K#9a zq}P%0;ta>Yi^r46dOM-t;%Kj{1R#l7tl=K55~M}BMO0y(v4a(hD@zTlnH-Olfx2wo zr{u1TzkE-tY5Vx3@h!clV^0*`M(ruQ;kcgNxN;9&x2H`t9K7>=v&a5D>I?}u7_>nS zX4iHy^+d?n26~>cEKk09FAl$0Ngt@>dz8`~7}#}U6SnO!Tuzuk@=*4(h1WiBB@R@N z>W0Wiv!uD@FHH+&l0;b^GVx<0-&#I!N0WO9vm2$$;t@{q^FGN1;^W> z;k`m3cTvu?2VRL*=Wyw3%oqQkTK$~2CF*b-%EQAyD45^RQ z;fcse6qUQ)^wAv}Nk72Y4NF`Q?%qFF8I(36+c31}6sfg76?t59pHIYod{hYS5_^10 zpz(fE8Qv5+9(b9n!cC`0OihCqY!Vs}QH_AI=H-NrJ=z-69F?Tg<&-oqDI$6|4uh(u zgqNZH2-IlT)7`tTG80*S^4Z#Z_xL;FZ7~_9K)h?GJ2>u_qIfhl8?WdUHl8u$4&9fD z#L!7LU5q^LyR6V6+%g2zBU2}}dM^nC$fFmJOQ-3#ga^zz~{dvi($n2!N%6wP>@jNndPF>Ract6SYWj!ufx4Q6Z zv$#4N!tfCjx<&I;;WE9c7J9zR{I)ad@a4&+vOx8h~YC04YkoLOzJMpvx3Z?p$nQ*n_A zTB*`r656hF<~lQDMQ6_ySbj3NMwj7QcND-ydR>nXuZghSELU4Wq=am|QBtM4w>7#) zu1%CTX(%Yq*x1`l`pVrAeED`bJTuf}E-zQxX$V#DQTV!fnAYelw61sebnv#gL`h)A ztt49;F{bC89Xn#GEPZFbu!no82G+T5ML`zfrH=}veNXjPYje1Q)0VS* z&sVx}Go-o;PuiMW-ZVE>)K@ixpr5kcZ6{YxLv01MJx>?~bXw`O#SNtp3t@a+x-oq8 z8%m4ky)RK=)`S0*5gSNL_Yrd97|RBCkBpxW&%mt($tJuU|UEoFnBfVG}PchQ>nCZe*qsc#&^^0zh8PWuj< zi0XYaRz}!kr0faOZ`K=wgL=Bz@WV-nS0r{(EPH1F%3qYO(OEN1Fa5ll%nV2p)-9J2 z*yc5)5B0SAWk2tVO9^2r#EH?$FqSodpUYM-A`6lpUaXw<}e4<$1A@rpYVE{i^Okh|RQ#vL|5uk(ZIW2z4S0E9|=SWOei%CW;bH`x^5 z1R7~AQa|i-d%{&racqIo6xy3ouw%J_kOhXRF?RN=GOtt$5y%2EasDN)_Lj*Y zC}v$g-*H3d=!W(sVQyRf+b%rU{@yfxv6 zdMRNfIoe>z@$PQzf>ysqw1#^L<-&i+H;FkMr@a6r420v@#%#qE`Z&RF+)$q54vfN{ z;kX4!B0QL?_?_W77830cDy)khzxLebvD9c|wBl5>w2$Wb{tiRN2=@vJi%$;?n$x|9 zutbExg7UR0##3|u76I22k7PGdNgw5o>GB2T0bZ9k*SXVBXgU|Ao^W0{VRkMKreVL< z?>0n|2we2%B*@;PE{ffYY&2|m*=|ScqckTF5UCgGCX*J5LcoiHXirK_2EwpWuLYLi zC_*G^naHwF4&JdZTe5@#&5KG@k9!zw-PF%wZ@}TtUjGphhj<6&%d&6UV`-Kwvl4;k zGc8d;KNEGDuaw>*NNyi}yQsNjHC4jl7_uv^L(|>{W4MLS@fO(D|7*wvzA!MQrLL@2 zDX+Nrk4X(=MU$@E){PTBkQ@D)T~S>fX^xM>CC{@rs$ARlF48>ix}Uu?PdKc*w=I%8 zAVjEENQ05fRv#SX_up~p+Cn*Cfq6HFp!DmZ>hgffT6A59iDZwnENLntxCFGmU)-F% zFuH;0q%JlP?4BG3VA*|sw^nKR>cIHvI4iao8Fk7>e+q<&AMt?Qfu%j^<5M3BwDb$( zdU1;Z_@WOHVF^gV{m*`8a2p=NecY>HsZl2w`Wd!BY1is8ofIJ!E(AOkF-Yh>oHfnJ2d8e4I>L4|%Hw=d=aSs{pq~Ro$H_AR_+{r%zjc!x- z&{q;NM>!vsdAW_tWDu@pnw7YZA01RE-U(4~N`k)ko)PZ$2D!v4) zh@Kap6h`^Wv4M4`G%L*er|}I9RjKYr3W0t$DC{c9!eOhtLS)G+6nn9+KtGd~oO7Hr z+zG_-s=ww}2QR5_&~yR=2tT@VAww}s#j~3vvVp?~wfTjKkk8X8M2?^KUFip6FQi{K>7*AkWSXsJTXoX{wyb=euMmcUbBDu^me!0LyP)|8?8 zsg=`c3M~7=yfL2a;<@!-BMcwb2P!Me*s;%&$n>Bi*_%lnS1ciD?(#iIIWLG;AERJ5 zE>c6!%Xr__7p5OPwyXB2AV+TsqzUW5$Ck1RsDZZqM@baw|G=4iF-MF_pq_wgGe)E3 z2=GJa3Y)dYP1PHTSM@i$=5bUq-l23B2)R9_O#zREcZ#Ue^{VurKd4-z*BlGa;$8$= zuS`b3;TY`^KjIh2=zTW?mI%mX(TVi3@>>#PNZFoE2cSQ`BNi$4;YM;b=5n3IkoF&!xZ&Z$r!^ppfi5c2o7 z+Nc$NXaQIv*+7f5b~$+s29m4LEkGYkrhJTmb1AxlHTdF$8op>AcsvCB^>56>(N$7~W5s$f3?ce+2X>ExM-6t6GOuA`H20b^Z?oRf>jT1iHC z&-BE#D^@qtJr0AjdR)zUN<~dB&~z3cO|xd31zl8f#~q8+@3x_I&eWcIs9E-Ln2UQZ zd3aDamO{a#iuw2HR3YfzE|>&?C{p@hK|2-L#k>0&!#pRj(9JQ9XHic-L)?96ZwM2T zO4}$2v&o5E9f%BiFkD8sVjQoUt%`t>1o<_iFi4cXmOdj2WaXv6SeBB|4D9z#R_|4D z8y?CI5-C{&W5CNQOZkvb*s9sUT3E(IR8d@XE7S7$8xUU&n5ZE*Ys=HgICdm z7huY|z{v6iAQ&>-nt<+U)58fjL{w?H0=Nf57T}DrAx8*&nIV<@KpB@2kE zezd{uTgVuA$WBa$vo>GKHjn^T?hpN||1e;PD~K=EU0ufl;(QjgR9h5R{tc>X+y=FF z1ZAjXQSKxMjsbUiUKByc*SnDtf4j2rXLOwac=pT8Cttcu!m>sX2e!O1~bw!Qq&4u>2OgyAdi@Wzn7R1&L_!EhK?Mm7|CaAXznXX5)$ z+ohe!hwuaS)zE`lB8iu{O%JJTpLs+3Swtyyi*cutm1B|Ri=6Sk3qbH8`dIZK=vNhV0Fh= z7>2%p`oNH7oN3fV)><&$L{w6c@x29TUkN{%+r>LK&Z(7?1P5@*R}TsoQ-~dw<2-#+ z8AW3M>{-Hvb(;Ga{d7^q$Zj`~WgAF3H60~L4CB!Y3nii6Gd3*tVw2!5M@;3ie=_4y zwQ{PZt;tAgJ?QNRjMdLQxWWvyyTDe;#R!ioa(5`f!a~x6= z!Ad%#(DaCin2iI>g@ax@eC@=9e!Wo6B&_^%KlNZPWXHT{S)?pOLS26{}&un23_N*PSMX}Fwy0*9M?#C;5gV&UnuLmAu(ZtG)Z!nCe(NL*ui!x!;@sXzYYtJvsU&7S-C1b@?nlwQfV zllMo$Ao~3U1QSW%Kn0F~G?Avlp7T`zTE2%huX#mb(gqG{j(|cJOIQ{lZt-&5j)3Vi zW(h1|vEFM6$;{rx2Jr8OgK{60xy2w88C2BUZOQqPMgrqsx(vj7%sHh2vV`5utGR+jQzRZb`+!xR6chkHL262E7&1cJNh4I zQ6BW6tDwCcONwka#xzIzIqF>!7TWlE1tr>(EF7((z9%{qrpg!cY6o(lT2~`$+r{-- z{P`}&4S$)jTtR@%m$=A+`T)P^R#B*dRQyD%#`byIL{SKrJ>o^gv9Z8@{R12uJ$(o> z5XSvnvQXCFXm3tsWdEIOA(o;4^q1g^BQ{J+=~g{^;a*hdvegZ+29b#neqG8G&k=IW z+g7>?n)Ci@xo`8C?v_{+{26Egr?!7dcapoChU$)><|>;udP}UOndM*1G<m`z45;+@wq-^tFa#0lvWE4G_TsEDg#v*Sze;>@#APhep0 zw+YEo27uL8DlTk~7k?h+G?u1beon4SF~s~L9)ry>(Uw**}c^Q#p-0@gVcBr zcDfZQIeOx&u^eIUHN_t^E;kl_n9`O-%oGtIU~)I1xrMwxu_KdVqcAuRa8lWsDT^1M zPKW$O(1mv!jY#dd9U_J5v^TgsyvHPUCi|_6EeqQB^Xd@PQE{6Nz^Gm?`fG|0)YrvZ z>E<|WZf2fzFXQLE9`_H<#Z7H~X-Rq#eRO&#Z^yWTiogs44uTSJ?XDtaiv1!|sW3#f zMRk7#-S^vDx;k27n5!;TX_G;U531;|5D%;|fZJ2iM2e zqtOyt6bZ)KPactEs2QxQ1P$&wtn>8uzpZE)Jx*@XKYly*F#Z0J?+V)OR_dmNGBQfL zLUjfK{=gF)lD*iwW9E=0cd$nF$Mxob6WC8knJaYwTtwsh5o0k_9>SDYMMx8aGna0k zxd;6hahpAJWbL5cV5M)tO`j3 zkrU4W+B-PS%e+4X`!E9U$n9jT(T=U*TF^i~b4`{KVw1&GHD{i!_q7|w)>^{QwH?WB zH{vvx`uH!Du{?YaG%1_U6%!|(XZzn2MXB`G?Q7-mP)bH|L)OmAjhjF5WUjjoAm7r4 zK?3M4gElL)Z%qGuGX9~14QvH$S=BRC(8rLx>5%eExYw8nydJdlDj+qkpE#tQ4%Me+ z-%`yLmp2T8!nY^yN-{;tAz()`kZ<0H=&!Y`Qy&ZwmY{jL(|aD_%|6uyI+G&0Y@{Sf z7LBLgi%fYF%;*SG4T!f8(BAv!h>EtXq${w+RkA5DVR+nb=MJh9bh$$g+*sG%ggtBM z9nh=s5JT_7b5zynAcz|QIAT2K+KXE5tdPb@OpWLwnb_%1dS+fO?_8Gi=W1IKHK!8v z@677}UIQ5M<8GCNiDqoY_f{ZjB*gu?vDCP55xQ8SXK9)Z2O|DRtX7Ijn1!(r@}t*u z{)$3MA3LSiF0*S+jVIE@ep?8Ka~nj1X!!{;pN&4GnheE@tXm?pUVs)99_*0Ldu%ycz1^J-EW{L@!YC)@H3}n(me7Jj z08bM<(!RZK23sRIX@X|jN(X!{3|`&aGGbqkA)-)Q*26g799<^!pv-o=t=nPVFoLMs(cG}&8N z<5IUh5JptJCwW6^kFg1&kXfgMtr;2koYpw&6DYS0lS*Xo(#zY|6CfHmQ6f!Du-EK(1WRBGi=O0!>-m^1p!YdpY zp=}aQs`lmHJc5arL#Drs<5!x-+i8RgtOuI61--aK%$CbDjZ4Pi?(18QW49t8679g= zP8k^DP%z(SYLLAj&u4f`^sF<~@T6J`1^5B6{4ef0?7|7a*~X$?CIXU1=6A(BMb*YiMDtHHc>h!ytbM-nP2#YmJk>n|fg?@w6{D*Cc zJvTi(4YRJk@i*Aa|2W=QxRTkjUq*#10y`J7cbTG}KP=^_ZCx*>z&$fx1wqAryX!mc z7aZ!v5Ln=>k!gt74}HP~Km49L2$Uk>;VIusl z^;g6FjV!PcbMb-=jU}@IB2Vnuy;9>gQX~;dxfR-^3HF*R`KP-#xce&h{PH=(^QNG1 zi5OmSvs1unjiIo*8WS48+NUq@#C7n2w>PuvfsQ}dB6w7v#{Ik|mrOix#?3Dv66|m^ za62(aw-lq@}@=?9PmX;J=?9-wT4B~2iisn47dAAWL9r)xjhL@o^ zo^FGk*!y|%1s5Gt>rF;`ZWiBIq$T3QD3^3v^fcx#i$oV{0;SmPPejxrWM!(9K1w2% zFKULes~q=SlV+6p@Kl_fWpB3C+=D;7KXDFILD|mB4L{wr_ohiIt^AVeBS{BY%&%fQ zln)zthXZ0E472bb%R;Gr;^ zRqkM^hh*lxIZnv4I=Y~Fe#tS z_~o-e_0^pLDl3wWZB6WnmKqkqcD7Z*h0v+&KXvrS6%u3>&Tx-792h9lF1 zo$3q^qqnyKckfSA^oDjO;@4-Z%WTve)!GA5EZ#pM1TguJD+1iRJzjy`&jvwByi<;t zJ_QiDlLk%j>qJ_FH3(;w1_)pU6OE~Y9%E3Wc(I}RLaOm%d@FW(`M6Q=Z=mM7$D6~8qw?wYt4WU{BZcoH zlY#hlz2K8`*R(hG3yvq;hVU#~^Yc#URd3{qo?9u$U>6ipj&1+Q-EFQ{A8x448*@mU z5ppkhLBKGX?yWo8dIvW2T@i!7k^EkjXQXH?v*QJAJYxCzjG{fgeT&Bl-|I-;!6KWG zp3qPIVUA%o_!}t3mJPvZB~H>vJ>n#)htE%`_VNj|5n5Sa_=Z=(h{tTZni|iP&K)FQ zBNUR@Jn~3vUYGxBcE^3H`FpiOuJXS29KA$VpnP9&+ZG*B%h9k)A#nNwjNY+bCCHs_0RKq(v(AM4pHJapcB?7^VvLg*?@OzF{^D^h|IC{cE$M6|QH! z!TTW7b~xQ$yK}jH_nx!!v(~$_B;r~-H-DT!2j==l;B$-vB)sr z)40Kv6^$+45%5g46nHJ$G9G%si4@%MEep=`EN*+Fs?9LRim^jQLRZ$3&M;(94QvFR zFhM@?h3-f$UE5}NL1h-A9$UxA7_c>N6;34esW~vrC*T9M+?LiGC+iZDWPksw@Gf1i z`sXwg&@=S?fRjBD$9q3+k=o;_!bP5Q2QD6&eyedF#aYkV`;M)C7obnG4CU*leQyad zrwy9f{!efuUK8=!3yw~*dv+*zs+UP$FN(?BItbShU*{3JyTr^ZSI@S@G3h{{!or!% z!kDTm*gtP2-CuSjpE%cPOiRpzT<-N{WIEuPMMYbXgTxnw)?`_&QdTvmzaqse zEJXI6@f^5wg4aWd6y56w0!7|A24IE5n>0{3HT^1dD zlKE{IY0`AD&p@vq1jdf|DimTMJA@B2o14eO&#Q9RxC6#tI2g}KdPg-&a8b)4`k*9F zWRIA`by;B3kXo-%Ii3VP$WK$2w6%1k~{tD>FO_*ESV7Y#aZLgZzr3bXu1&i7h>)&hKAJx z*TlWUM%80&x zGW^j+%IW9pM%?YK`NKiiRTi(;v(2b)AI6T%4S9Sq_Gh$4Uo2$Kmqo&nSli3eaW}3W z_t}TN?(p%~uh8-@J5O)UjN3w#ogFzCU$dK##4|T1+Z(dh-e~$o-fWng@N?u3bDl4| z4+dE6zU>h9+-bd0_EcbQtOt?8-W}OnqLJd_=xBbVe&Y9o*W>;7y@Z`kH*x08O*wOy z4Gh@KZ6?#Gn5V`-jEtWHGoj1Qbhw@9+R-Kwys4xIa#LG_hu6Q=19(VA}*ujSYm|=Dj%lwlc%kN6R&1Iw)-!5^#{P^?v zAH{#tgHBg`aC}l$#rd!i;WXKJB9qPC?C%%|hX)|M1eZ4X<0_(U zf2;7%s)>VflR2{6b#2(uRd{521OLFLd)j&g<%Xgsa0g#cR#IAwY}h|wm#-6>{Mue~ zi-SdX{oZ+nZtMjHgOfWWRjv(i<^x}U+=Y4vV8q@iz@nc=jNrQzgmYr_oPPXHWU09i z1yq=-m0dm`CubQN*n=EuycuH;tmT>}1}zSFX_4&jnmuN%%BG2A>K$BGDiMF&@!z$bGS0qfx$1AhZhjNEc@$aPVpO z!ey{Ljug3k{P$P0e^C1M=ECnQn|=3Y0m(6Bzp!!w;PXw0Ol${Xt3=vB)O}+|H9sq7 z#YKob-XGRU}&Q$l0h%dL8xyO=Wp0@}ln$Sqc+*14xA~vUL93Mf!ia{#>Ag$reJ0KIOYi zvnRWdf@OEY9Qj*7qzqQCc2I?j-}l^y=*`STCNXbHN3Zs3_z9>t7yFlfXBf1J)gaDn zESqxh&?U2l^+Js+rhYbX?6?ciyX2~!<;rnFPM6vrWZp;xRe$8!GXABIL5|!$w^r~1 z))A}iJF(EBZ8?ob_8AzOYB9ic$M4q5v5r5eAz{HC z)Nn-8+%fb28F+UQnyOlP7H0bqy5q)VFozx_g-9qpThUcfeY@!EAp_Ss0sZ!*;K%rS z0{HQcA$yTW{}kH??Vj4W87RDN@P_+!E&b$IkOl@p0RVu20BEX8lJ0D*tHuEa0GI>) z|DncWVP$S(@*l2IwUV^$KMsVR2Xz<^bD%QwmQdbHG*R>Lmi9Q&7jnR7Y$Z6D9H-HP@Q_|{hZ?Y-F@$V-bIfwPn6tH29S<=LG* zBVWF+r*?ZE1|3(UjW^_c9q@W@5L>YWd|6N7FqUdua@(7e@eaWA{9tz$eQ=DeOKfD@ z>nnv1at^MYSjeoaM}V2c+nZxZkJXJr>vMoOfh*XosGBR6bTqkb-VHSPMPc5(Si!g& zM^kPu;%ID5?2M7MrOdP3+^4AB7oz77O54jK+n}%q~y1(M5 z2$TTYNU&G2Q~+lgH7(tDy+w>67<65|b%o_FVxqp90Pbwd9e=N<8J6jZ-EVj}s@zU5 z#@)1B4=fuDU`SeYB*f{1>+4CALOR$5$9&syZzsFAM}latK`gX8vhgML`1`vdGyN=Z z)AEP4L~i|CToe6CfiEo;;cJj^>JfAj=W$CN(@rM?qR1D6VEf4;5lr!2jQ+G3$WGVF;ZNN4b7aO?#lP_p(p7V34 zbO}us_$VD&XIK_r;~++am@(C6Tn=ZWD^Cd)dVde1GOmONcS$WwuY!lvpilK&JRtrj zDC+tYtXij=45(K!XjfuEszE0%im}Y1m}NEjZyh30Bquf5joZXhZyYr0U1xy zks`A&0RzKwGW6Lvc;F>;ynOx4EZaZv4GO4$CbOuWBZ~GaEreeATgr!31xE}-D$O|b zXlM_^fb;Qu*aP`~F3007F3TIP2Ryn!A00WtdZG|Krl4FXpTqfl-i8`_S|Gzb8yJ9 z?w-8?+b+lja_$Rc;WI@u(j`I;cyvP~Jm@2ZI2p$Re(xZdqY3ODQ)rnfUx;nC=4d}e z?)WjO%r+@CueIKG4^j?8gs2bp#!3QtzzfP3gHRb74Z9kY5n?!VI)FT;{I$qEiPQ&k zRMO(Gi}K32QTRA4=T(N&^&r3Oxb)^JS>8Zu=Zc#&;_cVgmea0|$rlY_4*Ld%E%fUk z>9einLMvU->s?8y!)QF<8N}ltr}sDaSNR5xU9teqiRT!z_K)Rq0LLoy+Ws;L!Q>{Z zG@q7j)liSEsn|R|qw3aG>S{gyuNU(F0UoN*R2J&5w)QSL007PZ@7_?1LNs-P-*gEQr zx2LZe&OTiVPIG)KNf0}`nqPCZ+*8LLrxI6e_0I3Ir4I(H)@E;ZtC)>nJ&^5-=w;8= zf2-m;CDYBz;Hx*zy{%l&CDk%zO_m)SY%N#ygRL93sEQhAk*>9B?<*k^xqMo_Jw82Z z=O2WpGpjW`7Ne;wCG^3&BfnqR4{N)v4r@LX)~gqT+hE#O&PUD{p5BY^f!haqH>i9O zx@jBkdS^2s)$q~g(v^3S*Rk2uveg=Obgw!Lvf3BYJNjE0J`il@f$;1e%#Y{0=bC}g z(q8z^(cH%%{Sub-LYG3a`W9g=3v6omuU%`3H<)&jeEma80IKn?LC4Kh^?&HvW)J%|oB z#$zH>!DtVZuY^T~+?D34EA3QnfZPT`i_fB7A)-P%UFHNBo~ZN$p3Ay>4K#SK|LtN> zLIr@&zYB3OElAnId_M>ZBIhZ;=hxV=bm&axC}g^@r{T7Xz>^UaT{2h42(P})HBQN- za2j-~>i!{t`scrrCb>FAN_}EO?_t_)H!< z)Sc^9&^zf6lOkPGq*|5h>9q}qLmFSL*~fg*K$GY;V5rT2k*y_U(BnVRjE4e|8*;M8yo1~=uF^C@VZYgPJtzq*k zLM3b;M71D+ix%97pgENA&O`Ey&x-0#`kUsC6pFKD#h}xEg(e9?fS2g8bK`HPN@7dQ z9>6&k$4U%Ap37%V@Ls?9&!P-c$D6x6o<`1|fqT}E2O7+oKYchnHU8U&wjCWVOpo9O zz_o})5S&mJTwi~eY?g}m4@G#eo7JTEZS_Hx!9>C)US+Zwi9b_3S+29)B6x?mWXm*W77;v+b1W=s+QSUgoo448N@s0cBfb@<-PwxU5;Wxd^5JnLNgt@RMyABGnM_+g5CzmR zGWUAC!_X50QAJde0`U?HH$NDI+5|w0xJ0cNrwl789RfD;SUDo&7~o9tn46z8Ud@xd z*0oTz;4YAyKJbW5g?d*6pD_DEqS^QoxZ@$pgimY96gVqpK^1hz&3Qqdm6#8& zgCqX?kip{Wv+k>4RsPi8D`k%({zkq*0&};wlYEt8N}`DcvWs?10h0qSt>mu4hO^45 z6d7?4m=K&&e}caw=5U8+%lBf$-VbUNghw!mMXPgCe%Y&TEUC<5ocPMEEG{9T5G)dE zY-|!S9zP$RA^;rsTOn4)HFmk4!kW7f;Y#>CI5NkebUIP8lM8_=;l)Z1GPH-DvJeg4 zPh@&Pn%(&!Rvx&_{Z+j|5fxr8dOM1*06%GcM#h=av%;i;0S6%{Pf{9e3pNnxTZB`) zNuqMQU$6Hl_*!q6J4d2nkjcmb)oTAM{u3-BhX9w`2EqI)nbd+>G(;*&WSvlPrafvs z5ySPGYgab+k$+@etSveEeRXnN_?J;m};3^@yf&G8MZWCs_MbwQF(@=TV@oVk8|spb;~bm9Rf>5fLqJo6R~gd|c#VA4Sj3 zX8?=)dip{^)=#{nsPK5DAo*eZ51?wKEKt%IL74E8s1k;hWxE6xpS$L{&g%PUc`Zp* zP_(i`mKUFpq#u~~ar`_&g(;_Xd}>Eo*)Hl;f=FH$pbu_h4_pXvY~!`tWDZahsk7&f z;wFMT6nSMnO3*bI%ahk|8M4~~t7hebuCgO*#nI!#j}Ed&K4kLZkx=add_%lK8$fN_ z?(B+mbJ!S}9p^;Jal_e8>J@!SmjNPCztb%^oq(Hme8QtyRQfr*XQ&W2xA8bF+pb+= zcs0k}2o2xd%COt-kWbUUu9&=HZzkp&wcS4&B}Dhkf&-n+YNYN5VN z#*%b3;8Ycql;EPXs<&)Y_W8uBu8KVPi;|Vhf|mZTv0A zEWxhIgZDmLfPWaMA%C_c%7|m-*(#}X`GYH~an%!TL6nMP1GzgU_gdLq+EQzlTf3S) z>IShe*)!17B#dK-CiWi#0tn3w&*X&)6(uspA|_!8O%`A&H(77Y4!*x_#~Z=ddree0 zwIr)({7p3_Z70rsTAFAFnp`ma`!!}*4`vR5iS3Xy9Mq3$`|jji*qMrPc~d-OON=bR zxC&=^_hm{0KU|OYN{YfqQr=JZ)3G~3%DTRV;cL0(s^zI(v4WNW$`iLLkD`tk zdI+*`*N){{YoLk?{fd!yE^;4mmZ)|iK#~kp^zx11_!N1ZY`lfkM#W2tjo z4fqxt%rCy@IANIMk#zAW3r)N{5hoai3UAO^G&lCh+ZQNr9;!TfV7aWQ2iP(@h*XIIA?w3Uoi{%RTf89++T!!Oh>#QZSj zc~I~nmqr{`X;|4`hQ8$og2nJY<%I8MnG;PaWFF0CbQSbc1MJh#$K=XJ4@n}B^V~T% z2hlHROq?s5<|kx86u7&jWG?NmXg|C{NNlGr$RmK_%p$Hr`{~^%%mieDpWZbQlwbj{HG4f9{Ixj}UBIYend(k#JT6tW|7t=)_;9gJh_j|fLDlkt%0;jOWA zr=cj^>1ywY zBaSq39jgmi$d^DCzL#vXOfe>TxUQw&>7_AdQ=WUZoT%n0j&}xJcfIlT`MAg)cB`hHkNf4{+d$CW;Zr+j*))`+Jn zbcJ^WwYOTfo$V`8PoVw&C=tYLO5!CfoVvtO-X@cL5_gI1mu{X3_*%x@3Q;P_@N(SSYh65+LmA0J} zWH5|Zsf*u@I&^it|4_~gZ;c%C;idd%T!OnwV!flm#MIn2&fDvgs5& zhr!3Vs5yt>&AYW7Z$E;$XctwoFLF;j$~}`*^tZj!_@mgHWyA;%gG3GAH1N#H%aKf0 z2LE{CC&_3t$V3H!c|gcy670QE(>Qz@KK$!v#V~yR13MuWv{Q4w>&@`P`{gp9C;S=V zBB!$Sh%)$#1tTHHS~yrMcf!GaX5V8%AADLN?puHmYmV;4tD1xiFX9msf$&uABhzsk zG4(v558ciwuE%LTO=SCD6sKTL?{wW|v$<_0UqDpY_iE=YrhFnX%-tiEy`VXi4*OA3O}8rf^jvk)&+(hjcwmI&kxWNWM_T}|HgoubdZYT)!% zGoL_ITqNpu2` z6xUKV-^HN}!^f!=s_eQ7dl=1PDjl84q=)$Ki>x{4}kU(cgi%C0r z5v#_mQNV&p`F1>I#icLF(fKFf_nk>u_sFyYJ`nB_pAx;2H%Ro4CwjcTJp(`Ty}D<$ zz27L7Cw#jPrFwk6?~m(J{9pT(rh4A~&Gcqhu)gv@sB(8gJxuYA6VQ1s*hV^8UfGv> z&|jC0vpLB5Cwd6o^u6yYU+Dk6pNd1yamfM;0PsouKlW4qt7~I!<7DDsYxmn&7{>bN zfZh7!-3!!=CsRyPD!a2*5tA?mi>>wi$ANCSP1_DV0pW^nZMcS_;C9a~vVZA}WToMsWA22=ZR zLestQcky)Ff?6qYshx@{ACE14DLA^NwE?LkfPNz4s+#Inyd0_c#vs2#^-X0nqq;1r zO%Vjrm#{_7DcK*QLIS(43>d8^eB*py?63r6T*=x&<4hzEN*OQ!85n6OG7<#gpV(>% zN-(8kI${?Cwkl8yWfeoPU#-**%0QK`lBCIr;^8HUK5CDKeQmYwg^W5kpvQ%h3Af+7 zjJ7v0PdJf)HB6mQIPZ^ZB5|C#+Q3Wt4`1cflrR4?idYn)QyZPE91RX@pRK+r1or7P zLdse*rR#V-Z0E5hh3h!tB~2e&Qt!aw~gFtri=B&U1 zY$yjaGK`LG%%Rd*^c6@)@-p_dQqb5CD74kn8LR=?$EQn&82a?D$ONp_)B4sUmM~{* zT3eGa{;wx6z6&plEX$|VyFBd`HnI^GV|5&kkszKnRHA&tk*8>6mDFfWeX(VjzFDmJ zv4y9n5;#s|K^#bT_lC~TgX`+H^zyx4_Gses*s9Bi z#69rZ2SV2PwQvW%jvn~{Dkg?>GU#Tet_r~f@`h}?>^rg>fNlz$`2rT`+|`fQUnc=+UQn}2_-(C zae@F4bFlBhM}t2JZ~bYdER%o%d=g$9a>n=n;(;`9t)|oXyPts7J&OB{ch?ks z`Z*4XjDHKJBdbwW-2&w&)!3}~*<#nMUQEw9HH(MT+#iL2q1&UGovTaNYgs@Bwul-R zce7l&2hqam`>{W)J4i6tHm9-q@XvPErwgEnH1e>5-;LS^vAFpa+uYWGT$)H)p|y_a zdI>I)4l!+a!k*^)W|w>r7h^fMf38gEeS{;-oIZEWJ&XR~MvXGd!qf12i?tkT=@ag%J^xwik zVaeT#2NgvIcOrW(`t(DO5Mc1-t-ty~goNFQ2F8cJOu9>v^g2?8@$Q;R)LJ^o4`)Z& zrr4`TRn*W<`govzNwfkl4le_(K@&1OXrfPf4%V}OhgSb&4kJ+@ZvCD2@QAaoM!`?= zb<-Xfot}jElFg-C#l4R;>vN7-s#I;ZIRKtAi?j;o_&`(qcZwPY;{Z}kQKPp{!q^OSZ zA5T0}@KlfdJT%wfb+kzo@-WNl3Ay87ng9m}r1gZH1W|Bj$Mk@?5G}0VVZLawpNpnI z;r>`yQwc!g<(L-i7=c!HKZ&Zs00#}wQRdAKO*uXeS=PMB0!j2;+(rskLjPVGQOZ|d z29Si>i?(iL^+U=wS(?6rvUK zPsl>Hjf?92*8TBu|Eb4HBiAVheEey|pj%1mtp1p8H?RcUMpdmvmS=neZny_{>|cv( z|8aawN2yl|V&9FS-H~zeY?@0<+ECt34+TjbgH7JdApHy2gpazVp;lDoJ4~xcUOtd6 z2kVuJ^z+f%PT`}t47%%SolIt1kHOqXO`!5Kg$T>&IAJ^n*=y8lRyH_9dyvb2^{nJE z#E-jLjr$0AV0g*ToUiRR5OT;$z}?{bR;FM~ti%g(6CvakJ=&$A^+h_ILwLHLd|25` z?kZRlr+>5JVXGUf=(97eL;BV(*z2y0RDT^xizb?vZLoG}MEA%&$&J@O4At>ibH*O} zP=wprg#oN;2l2CULxhZc=Pn#Qj(!k1sy+UZWWwXKT}!f^lpqn_#3fJ@U*=|iw8xmK)*_^YVO2s``IsRLI zaEnsOyX$i!{3uVB?FR1!r>QDaq&^Re)F3qmbNAU;*_*4tY;y}N^p@_)3#55>fi*x25R~~2SSUWUC zg{p(vd;9k+E!4k%SOdkrBHvls#*nhmUZ_Af7EUFiyf;}$!;$t{gkQ?`o{S^tbUl3l>oUNswZ`<=bP&rg$*7|{OeC$c`x$*+I8BQ z0QV$-;$kk>pi3|wA{qn4_n=VW9T?og^8~!RC^pCWyO8=JX|oS@9HJ_*t~Fm*I?EqW z?=FZ$-FmXiv7I{WsAY~Y<0fa>#!<)(cd;GL*la3}EC(7f%T43mnm26#FyEKB{#@9m zFMdYnl=q4Wrz};Jt+#Qxrm+ar5qJ6RmI?bPk^0EX>J!|VpCF96EppWu;ijY1q};7>n@5NgbUk8;v@q98$ZsJ3gk zO!L?~%PnYpv?|X~p8gl&>l=GF84=v5m7N2ODet564-vYd8$t%O{fBZ1w0-!8H=L#3 ze090kzl4vZQRp@}G&cDYO8>HyG*{p4y7Wkjw^hCo`dX1+v#6HHdE{wNw-wM?N#%QN z2iHoJT}Jag-Ok}OUHQHXoxtg;8R>;j5*9upj&tz3yb7UCQ7vvC=erd_i)N4#71z>R zz7fbx0f~-vdQ!sojTdF(3Ln2x9Pp)nUT9!scLTxb3s@up^pk$+Dk`Q5u2L3{=Doh0 zV0D>w$z8Eb7&$fQ5fxkN6%I*i6$&{eMrbzuC-$wd2$&g_E1LauT)58~dH;ewlB~6! zBA!C{?TG73SWBTdCj>vFM3XCcMRAe^drV1%yTNTF;ydKObfck|*(};{&W=;<&imie zL*c4cZPs?d4zTVqdtC3tX&n9Oi`zC8qQ{eIHZzlOz>aSp=iqxd%RH%XzB~zCz%Dn+ z2JM{srj>=8BbbrE!+rOdDhT2dssAouY`O}VVf~;X0d6U?&|Q`{AT(LJp4{}voENC1 zI~^@|+a^eoRr7umA02(s4;7r6F!M$6${dbtuAp?PLV_8|oePq=b-}YSaf>oSin z{KLmu*_h>2{bSVFF)oZgzx@33Fd?sm?pUh0c`>6+^0#XgV%|pV)HxWq$OwbIK-6q3 zeRwl19XmU&huif&G&KW*@H-t7OxY9WNI1t9wW&?xGAB45{r%)`DsO8shG$&T_d(%i zcdp}$=?fCmC6^<+*Nkhfn&Nb6^mV`G1uqWhVtizYp`9F$X!s_h$x_RFlF9?S#lxxZ zf3LgTipLBWe|aplzjJq%|7EP}VDO=C(GDzg3vCs&(ul2g3KY z9^-kTYy7C{F_2yVYw70GZdh(7dA@sSiVgrSzp8G~ce`3trAp*K ziqZW@d4;T0PYuhpmVbr1jx6xv;fTD{TP|N&_wI@pgW0s|vI7^`XuXxp=)T-I-!fS( z;J|TRh@M`Dhc-|5fxZX)g5oUBp<-Hq&*Iz}>Z36u35MAJqwQBkX7%RKE`Cz3Ib(;l z@2X)LsIO%cFH6F6+5r|??F>kD0rH&$bE+A}Gb<`Vj+;BxUzOo_P48x9$CJbJP3J*4C|4$W9O_j!Va8u>lmyn-z#x3UX;>ADc`_-L_>5 zzI!}nr9#Neo)YOyxQ?urLgET$S1X)H!w3;>R!qk{K!dfVPE3>)LNfZ) zdIrs62nMvct_u?;$+S&p#%35F6j1v>#E`Nro#%Q@t@>FbCyyst4&M~k)-D;2*5+%C ziN@RFI>aRY4-x=A;MDQdbYhhhvc2Mlg;{ZAde}MdCY|4_5wC}@|5-*rlnnVuOq2}% z;XL`3F>)c__q8??qp%Q|WRtQ5^PlYXOCEbpK(o$W${A$^TyuF`DpTyR6fe-Bte_Dp z9dk|8yS+(JBLv`(ZJM~*9Mjox5{ARDQ?=f72LM@{th@*g-ugW#t;T^3#k|6vXb-4!M6x3h;mgdX-ixavKb^Y+${_ z=TIU{moeJCP0LJip&@iCq4(=tlIs-i{kL4?tCo+F+#}7`Q21Fe5}RfxV|U!{W4$o38{iapdi{(|XH7gu2EFoLj4iQhQ@TjwF^U846_UfJC>;avFE9njZMBk`6dBXfL zmV|=g(Pxjf_)Ajo(hK#>wZ?NdQ#wOuxQjAjUs%@kSNQ)95;7j6kX^sv@cDa@{x2Z$ z%gV7dari|A*4TQvApsbXkFSV$GlBgEURESjZO1u+B1a^0%Pkw6>g>D^&jjF&yQ$1O z+-=zs#Mupt)Fd47u!{Q{3Uwxjh>g|=}e72YHSIt!Yf*B9d9q%q3Bp^%UhkQ zR((X(u^oS$S2ICPQ0FDFe(ApSIj}1$Kh&txMN~X=`BX0+;1dI#EL0)m_r!e|p%WtH zVn{f$lio%Ie>i|yBGH5O<*dBFz;Q0pq9hz2v{LI zUVN>VP2mG8ODAFf>0IjKaM^|-7f9NV+59gf=;(MDmcN&=v?RWrbR22WDl?P4Ajky{ zc~&3NOb=bYb%%1-KULp^@0qLaa$@s1RnHCWKJ-K6QC9K(s0qC^t0ebA}UD1D$MUAlOQOq$J^PD0!6)0u4{ ziqdyS3FPXYSv`EGVIg&tlaFda*9P16&*??hGWEBIjd7uZO6rFs7MNV|6r*mOf#{b0 z54$}5{~j_YPsmMRdRS`WOAbpWaf_;&w>G8y5^)y)uVd0erRyvQ1OVU$0s!#a#{3^S zYsTh|P7daV&i~1wzd=&1tYi6)0mXZ@mZQqsjIdr$IzMnes#&8mg~cgKsm^M=C5*=X zJuI;vzqhhzeRBX0Y%-E~%QJR{^JSZODhXaLnUTVh$7mHSnq|SB*B?p&uRD=7TbdS; zCZ{0v^^jvVwsn?#o_bLx(@EP^gIrF-8dsYoqfF0=N-<)RR-UOTj?bac?CTeyf*(q(-Ctfl!M2u9W z1?z7$TW=28kPsq)3`fklpQjEbLVW66;MaMSDr`8iMlG*@QI7;e)kKhdW@*$XytKkX zGw+4HQ4iwkP}^}3@Lk=$z|CGQDc@Kcyp-T+xSa?(OKuI(%|H7PB4C)V+A^sJGc%YI zLX6e!S!uSk0A8q6}@D6pn2d>yJbm1^Wk+JI)?>M+wN%xKD?E z+Upt9lp=Xg4zYV_!@JjG8aSIPmj$M}Vk1aPtax~4`t9KAh}G-T^8)BjOS7o{E*|NP z+5!1oaJEu4qxp~k9ccIuS+_39ZFMx<@ZDGFk*fX7A4L?>7g}zyUARoF!VGgU{*IXp ze3aBo5uozh{jIyNRgG`3Z!hro7^Own5=)n$$QPr&M=YZqE0N*pp5y^IF)ccmq9Za6 z-T4Lu1asoDcD^yZCj5pNE>OB!dGV%Lh7V`~>n9sBah!0>==PCEupbWWH+=G2$D1YJ zW@E|j>m)^7*|)Yz7PO{#vES`ZJ+Gm4<5~i9*>~n==>HC1Pd>*=EWcqn_zPdZ#I)nHzctc5xiDw|Je0^+0Fh6Otco6FQO!bkQ5~;wRLwsX|%|3JsOPu z^blt&x9SHrRjy}eXJ^h=4?!DXOZ=ngJ}JvqJuj7BYABY=SX%V9fMf9peMA@|w`{%w z%oER5qb4TJ6@nXS&XUsA^QlS7m_8LW#7g#%US$(uJAOPgdIH=dpME^ef`sm1E?-3h z_x9rAXUm_QDxQ_aTj1crKN0xuaPqXoadkRMpI)54Sq&chH9T|`W_7YndM8XzBc)zI zJW*s@5R0(Esw;4mzMmQlWAjb4jA?T9!8W7c?Qc=ehJkC!O90V?96hw3^LHEFumf&u zbSgerUCN?VU2XOd?T%T(G7Vl~jM=kl7ctJxsBj*1Ku+9q>4wpCQ6f|nIRAiXX%4Nq zVKZpIw^_>*m5ov(zl%|+th(&JUTu%HX-ya29%PI*rgS~oqTsXeZ$p>Nv=PkRWUwHH zeh)d1%Q={M1N6gg*_`|_=$q-hzHyF6%_sPaB&~}kko^q7=_`<})f(zCEG0*M?)hWzoiWp+s3eD;>u@~^KwkDUV|_lL*!aUq1?Wm- z?GpZf4?LYxwbsesylL|rc>fz^)YkfOZdmVEcPv}72;_3(pPt{{roH~Q^PzAtzpg)dwdEasm(8KE z0UTLyGuHB6K_LYXpm*@S)T$*X-U>dV)BXxBho3S z61MWI741{&2Nm{Qn}9j<@PA-Is&CU~H_`hyR>Uhl`hZ>0-AJ-Ea-cb$OZJ3$Ne;T9 zt{TUBRmgBMs>T0dL=gah2S8q!UYZ$9$}4z_aU_b&5~AH^BZH*O<7wDoEFEFBK9I)r zGVmFp8vN`f7SC78y_j&$I`*rR2dh%Bc4}B9O+L?9jXEG*gNSPd(P1jnWP3u)vo}ps ziih4lN|$NVN344Uj6g3>7^ZdCeyq|Jr`g#lk}hWi`DrQt>EM+Ejz(G1cBI%9Z0st( zHS3&a0$y7qFYP|3?#vtr>xcN|1%mKzJDPc?lFa^l=J@u?M0BN}G_=|loCG3<=EUE~ zx(NW7IU2HrSt%I<>(yjWyu0sIHc-;nQ8x9n#%MNOvRM z-Q6A1-69~}-5nCrAt53u-JKE=-=BM*`=UHvec$h_HLkPpKfl>?&g?leduH~o4=8cj ztvbE_wBZV=^r=T$H)UvJFQ;jkV#CFx2X3TE^tucwA^-dRsbb@kgA)PG4N;JQ-l*jN zHkdLovU-?mDm@&aV1R4eRY962g~vt&55lvDZPwk=+m~}JcwT6jTp!pUmoJKc@12WB zPr2kzF}@gn10qXjWK?E{=g3Y%#0CxFIO7@&j|tf%>gw~=+WThq0A1-kp{=MmXaiwE z-%KOCB9BLKmC^SUYb1#%0m*at1EeFRnq0ZBXoo_6T;&8esHmlv5c~5&q&+OuTGxQg z>I3M(#)$FQMrK1qhC*%_tkBTF!Dp|&^su7m1mr|}9Fh9lhz`{8DjmgRFPqxmhrY8e zMKfkXV7(R0_K@ zivu&CRwnu*k-S)}CSBzY6;aya_YooDLp?z}$ZWoS15oMQ=kkt8=USxQIQ%1e!Z#Xl zMX}97)Eo>acE@5OJm({9$9#T6n6}-W1dXzmvSIIY>yUhq;f>Ekm$@eO4CjS>chY4W zx=gkS4I&SKibS9HPf#O9q=p34ibgNg_iyZLVBD$ z@bkvs<&U}NIUyknPikS;ekgJs$ zuUj=PulmhGp4c#w$5~$b0GiZ0z*!uIKYZYR9G{!%J2+TAjL;ROqbC@U-hWq#_zX%| zw@rtPtGvktKNrlGalzNI&J;Q8JNgA`SR-HaLNnq&a`uWzyKY= zJO}4cnzmaMqh(}C(2@)jZ@*3eF-x@2OelqcAtnqWD-@U}(9_gt%tO<(LzZWWklpc< zG+ZpWODi__HOzBv4J2|yULOB{Y3)Jxm^SR+6%x)jI6A}>(Jp^Ed3^W=<^nqeyQXQ zWeJ^5kE?zrQI+0TOy@6+zsX}8E`$&hTM(TdNTsr1_w3a(H^Y;I<05o>I8b(&FASf8 zc&n6sZsyQ0uNYZxaa_-cO+@et(@ROelDVlkTv}|yG4!}6nxpeUOTV$ENl^<*OjYd^ zmb^Z5+^<7jv^MMLU0(iv$`dfYXxTtn?0LV!-iXR`t`QqX?bg8`WiZQQ=i&}Kxcebe zwHl|*G{JHHd7ULvIjt2X&LWvV{PRciFH4-2o;Bc1jQvCJn5LvTs5X@kHfH@v-|zT$AZzT+pk}laK>vG zD%Vh$dm{t}gQo6_3|(*JDYMycZCyO#^Bl#AwtfB6@5v3qzP-HvKH4BKrea9q>p(4y z7B4c~2u0$^xS94z$WgJk*J2&?JIxDuv!+i_g1Kiv{g74rrSUS`+(V?ZM*frFirgow z3zuy!Mz@7_<3(9`3vT11$1Xrlaz|fiNwE9y&m@5R>bi9GP?k#%B=+}?9}W( zGzIH+-Yhkt^uBO#l9YyyezDDsIF95Boqu@q)F-Re2XSB}xFq~gZ-m#zm+d4KbN$Pq zeRgW%mfvWo_aOuMsl78tpH`?=fBVtOo@R#%Fc9g*hpxS4$72RiBUjiZnshfOgf}Ds zE{EMO58B?XS)SN73g8@{f{-yTp!ML;*c!N?0E> zArh$}ePYjk6vre5CuNAc@;a7w%AeeHx_FE)HpwrHP_7|zQb8Rh_qha0fIcQsyIc8) zSr;SVJkkr$kPT&ck2!zGQUi)@aukUY(TMEuaJz4sK&%~A9`MX(@R&Fu39k7QWuc%^ zvwo?u0eyE9@XpnS6t4f?X^fL7V{^{es6sAFW0rhb%AeD|qR6$9%}1 zO}$JAL!JK6MccW;sl*eP=mj~vZHk#{XM^)DRHz4jR%y;`t)FT3eck)=kgrV?>r3Nj zJlh7AAjY&BE3HAS_2LGU{(Z3}5r`Dj-}u21oh{_O%_3NZ=z;M;>Smvb3(&F-UcS>C zE5fM4j0*b1@M+fiD)-Wa=W4g0PHbHq^lf&-^9>tKIA~mzs*{6hPzf^aqrFZdZqW;l zZ(yG6OvYfnjvYzCz^5n&6gj{x7MHig$%J*v{=#?B%udr{uEbU)r;0c5KdbP&7Jaue zfIa;^+Mo9_0ZyR($BJI2YGpIm|Lkr=hfx@08bXLDF`IAMpO?KVEu6jxv^|${zC-<$ zq}k{i-4LnKuD4f4vX*>q>6u(Dgr&mTUMtV(uw2Dfz4dA9*wntKpo)?~>Ur*--$G0E z+I>dEq&U+XbxPTf67ec|`7~i@NW=y>TANf8V6mf91l#*(qZ92?@rGvpI0AwpN^DgbD;I5aD^+7Kxcb+4X4;? zV+Y(#t4N)-Jip7QEjeajfO7{h3~&?9A(&(vQ3*6FbcB_*H54u)r4Xa$d_$hD&1)+a zrL7YZW?2f7ZW6urqW;zBnq`$<@&znt;!;0ZKMmAo!^H-tOC8y5X-z$&vpCMwm$jN% zMR)=oDGF%}KpaxRH_b#>wT3gTa*~Lfwx{PaS1m1wr8v-&D{1-us*#{PJ90=xVM950 zlwY^%%9Vg;Koy%P=Hs=cwu^<(MVd^UHm|Slrl$}0V(ODMI{f2Z>9a6+wYV{{VAD$K zO_4~CboHX2JzrWvoPkLgJo4qNOW)U0EY=IvCZMu)75b``Yb96Hr6@kUk#41mIL*Xx z1~MvB!Rtwi(A7nz1ipG)sTlokgUZ8_8bZ`3%u|CuM?0iBdUeH#@%^2nll!-$^|Nn@ z{G?fNL*ivqu)0vfR?09y)oK)?j3d$Y=Gxt1rbDk#n9|J-?FLSqX)0PFowt|F0>w;= zaC}_Pn57F8c)a)m9ng*du9KW01tztH?K2trL1;eCL40`?yA(~;3OkAfTT%$iT%j}! zlGS%Ni47eC3MG37)$eU{xzL#~c3xf>a#2oa*E>a1F3qw#Q#!p4Y&Sdi3m z4N!0Wy5q&bBA7=eJCV|-uW-c@l}D^ z$j&Cjp-UUq0~XSS=1Nzu+WN>Xj^W?r+&h>9U6vbG+>xx|P$6C_Hft9R9?GNbN;0ch znb&Btt|*9snY?eOm(OY>Z&HR*T$Ft+pA{K+Oi!@490i52Mv|WC`T_DhRs@0tm3~^R zkD5N?u7L*p`@L^&cLD-fZG5z=j-hfhW^JZU6L|=xEU7ylF%nM&$c9R}b#u#raKt4h z=i6r7I>af-13Zz8XoJCkI&|Y>AR6vB>Y)ZXqaL!AJSwd3?{-^U?i;V|TN)g`S@c_6 zwA53A4$~1rpP12BsWNSK z7j~&_lr`E3%Gcutrg%Wcd8yq3MB=rEWd?xGYdKvT_Wi^QuYC672h9uasRah zB+}W^HeuJTql-uET>|2*d%4Yx*7p}4#Vc8jBEAsSW1-y0!AWxr{V#4MkmxQ6PYcS` z*5+I-&xf$G@%D&8Muat#$$Q;*8-O-$JSrs1f&KWhW~IFXsV+J6Kyb4|* z9E5*`@Gayt_Nm3QMkzDeVY<%4H21B7_u!MGpU~ikf&5|sAB40Wg)2!0)9~`Rb$v_R za1{EIc2k1M4m+hqe8bZEZ9J~bK!*C=wK0KC_a_AS58c%!MvOZv3oi}9>y-0jAh6RT zAsx|wp5ehrN#vk`vsNWLR5+r(&b zDTArWwvjvATZXqEd2cpkr*~%pLY=Kp38M-1GJ7-U`rj4fBzJpo`(YV0;rXEU?Mc?U zTfZXUHeh~X(k@To65ar6yyc3{*SwBj99be=^Gx92Gxq&+muYf~MMuGmWYa!XrfMc6 z&t-m3^pzYdPeqDFp#~8o1E13Gz?_B_23&FdM>`OMLdKW$h6gv=WX@jmCrBIaFP~1wvp7UhF&eDSuL6(Ef{OYe$yi8)AqB{oU0I z+KXD6o}BkN9L$mmofsLz zF6}rph3cx}LW3X}Op#czv8@Wu$WZ^kGRTW8W@aaGMFXzgua^n8eEG54`3VQZG@9X?fYZu6ST% ziWEK7IVqL>Mq?802J;4OKlC#cB?nB2zpqGqGKBRDDrbp<%brBMJy`Im&6jds-4+oB zRF-cO!WXcb7RtR6b+6LN$1vv2I~H0!=s&rpLB_=2q4A8+Z+9=xH%l$ULfo#~UD9uN z8l_U$Mx^02q8Hx#_%E*mk>5i?wN1}Gms{C!cDp`5TTUz)-HZUcJGwhnE6sf=(DF6n zns)m-QiYkp7;+ZBF!-8dLe(I-r2#t)@52SfSudixU(>fBi*Ywj$t?c2r|e^bT-e-1!lzdfk>Os9QTmqQ|LqV*D_K{Z7|6(GL$S698hG!7k?l7I0IW%Db z{jR+OcOCkj%QCO@-ID>&XLm8VY*-+mQ*0oh=YN=h8|&FUOu5x|t#MkO-L=c|6N0aV z)8Ng8p+K6+_gUNTu_X4&_&tXrG*A4*w4h}zR_=&;DXNoGF-5-pLhxV*dCn>l6wfRX zcf>RGY9kJEC0;?fwR%T1hf0U0JG4bP`O+gNbt>Op{A8&U^q4eJ+myWAk~tZ5$ADS8 zRV*$+=S)6KQ`X@XH5X(38>Qj^x?O<;BpUG~29#w7QddE%kDmvtKTony8nRlgDW3NX ziC}2!QkHpG<?=|5 zhb`i!b*Yo6qp4lh*bYCHc+-2OvzP4!JphKU%wJGM6Ite<8;Wvl5AY4vOOBS!HnPp= zeJL!>r5oCbJ@;NLQy_n)A)EiQouI&JnnI&5sRj|bqPU-C1)!tLT z_53`L67qC*JseA#$w7nI4}L{EvB;q*7Ko^u3=Gla@z#c1IwXctuVG7&za}oHNoqVd ze)lf1Wu8TtOfiAf6(rWp<13Fl?viw!0u&p)lOD~tdh~^S_i0g>II_xS;Q4UnJclSs zm&8}kdzKe*=B;b#7B&@k%!!fM)sY~G%-Nx+Slda1NMYwECbfl_yA!6H+1q!#&%uNv z+><)}J0Nna;$f?5up+tUjyURXy~>KiYhDnY@K{JXhcz5oX!&CCC3(Hc zXDmyuOC`b*vs#1_T{yH_rGn%xYlRB48Vgbl$`{K3Ca)LbSe2+|nb6H1Tf|JnBR!}$ z)tv`&n&JhqP)p0OoYCmuDKlkUVH&HEwLRDsRuXi_o}}opI;ts z4FX~4HVo2*379xkUUBxraI`ZryjR>-^b+BH64$I(e$bHVl=T^e`sTP`GG&O>O7CQ&B$;$VQ0;df zf#&WI6t+Usd`hGZ9^+0#SaAD}x~b-lM$K^qZmJHbtK#ijMil8<@a<b9Y3sij90iq@++>Mx)Pb1?7|pC1E`)-9tE) zl^`tb$Y4*IDNaN_IwrI#p@DyQ$)RK+3cXREWhwB8D&P_>N{z-?z9fp*Bjus6>7mqS zsq5YWtH3|+mZWA@y_IN5658%KxdAY4+qha)_d8kYsOJUA>& zLMS0{E$@}uu@_VD)Dd=vA@*TExw713F%#{D!I`kny}BdP zO`DsbF%*rK_^MX@Yw-pTKXJwWVwP$)mCzzpKaYWBv6UK)@m5o>Uj8=`Gl|8 zrZ1+r;#r8eI$|xp z63Ux*f-kNru3ALTsndkFYMU%-U8*jww-3;))r9?Jv9R*9UV()7yJ^rAj*xiaY)K#I zw^UEkqDW`Z%HEOC$?#;PwsC)VP}G0@ndMT(a%6<|fLmP%H@;##x&2ifNLc^N{Y5$i zNVw6Xl_uAX7^0hnyW^wdoYkBG2fO=4c;x-OyBQcR?4yFlrtDA9K7G;kM|PDSA%}B$ zC@)MjVKSauw63PFrYhgEv9I2T;`DO2b}lXx$GIE{&8M!64|4c$%)2`T1NBl?qG zU~$pG6++&OdAS9dmZgUSe|$M_u8x(OTua1c3ku?nl;zpnjxcG<&clw6Pr$9yr+@$A zlb26u&t0c2ECFN-53NylZK z_?xAZYTbl|WDDj=<%>9m8sN`$c~x=}pxCUdW}2NfwC0#!B=lzyx%Hh;CLpF@lt~#) zUb&p|s?H*;voi{Z_Z3T=%FkM0URU4Zo4{0U!1ygGD3Xl_hz61fYl%MN zVw_+jwLL+}lQ%`hrk*MR3x-Cu&w_kkUJz<0mB@t#%;`*w1+r)6$w$y$mF20S2QC%M zG{&P`5??oH`p(Tk&)6$BaO6!thu~XhSD2#)kBIshr3Ah!z7BOB*%&K#9>LZ-FA13m zHLp6CQ!Mno5=xl3&Q}YiCH2;nWmEOp?m@8?srWYL$7JV5Tz1DI(>DcLSdy4yFhT)e zs)ZIBpc`8#z3pD%;+yZYpZRNP*`dP}ezbF$3zoAIY3;%bUQbL=iy{Gf6Ib~XR5NQT z@>@3A`L6HLkSp<-T#2cB;BzDuk?ZHQNytUvFR8{x@zBra*!&PhA+Guz+P{Eq2odXT zbVj}Qqlpi{+W^bc(AhCNXwhP^FiQd0Ipgt169?D>HmQcUOw7Iqs6|n%J+G(G`MkfM zRi(Bx&B&oo0Y4CG8?Ml^UldLZZ`Bki%f>msB#h)^V#0dJ$!VK%Y}Zd|?wEp)Dt<8| z>@y_fFc~P7r}zavLLxp;Ih5U>GrPIUE(~UA^9&Kxj|tl{d({wJ3bl~~G?r%8r*qkJ z!g-<8K&Lfqe((y+(zmcb69{eOrN&r1c!mjD)WpKH@RAcaha`Fm%iB$t&qK1S4!tQ+ zfz01YqJjl3yPD=dxCN%~Jz2G-R>;Dt2aN3T0n7PRe;DCAIU2LmTG|-sSsDRG`d%Z9 zHvW8YLCas;SK=|5I_L8Q(VG?VBrrMAAm_ohD`itFpznD|91A%es}0-T*FYj0qum9f zbZdi~Jq0S${gJ#>d%Iy34KE!6a5hTC*q|3q?ST6*d(*vGq|wY%h*Z*7-f0_N(4HBo zL0%?%?WR!N3d)Ez@d6IMs0a!BeoLBUel_LPJw6oAE+Rcbl&R_cNoY>90%m-)z6hT; zPBZ6Y)YR?V(COi=R?BW39NTIB{nWyf0QEx*c-ZrR^%#0&ARz8P)ZX66*2doPVKalR zk-f2vJz#mpz=+n?-bUZ@?*CI!x6IU3zlln4w0-3SXJh_^dKJBr~mEs8Pwju-;Wt=_kOB zgzO6KJTG*%o$AnsDrvJpY#8&w<5v;2$`c^Tfhw>alnrK{F;zFqwp8r6-zoH|R%web z%0N9yVQZX&CC_;=6F55!<037f2;|$HQAqxV*xBqT2&A8^V2e|@%5=`3@AW)$p6t+$ zF53KF)WFv+MQP31?ukWWD|SZ4go| zpg`L;k=CHVi|PlbaU)@6C52>^ilf(nwDivJR|IRg_g9wwD5`1*hH$J zm~mqwRV$Ii^ZU^C{*=p*1=wEuQdk*iE$mS~vCA89;9oB%O_is+QuE?7@G)RI*J`re+ zVhOslN698iWQ5ez!Cwk>G}^~@EGhKD9_#NkQNDgHZ~~{LhCit6;BlQ`x$3mB|9Wjl zJ{DRE%YzwH0f!(v1mDxRKNELznXI_DCcNYQ9PO*OHJnoouqwle*O>-L2?%*Fy1lo; zGS&V17G9%eA0V->!(%HRAZ<3?iwfxZy)Imf@hCiFL_K*w?ST=DkfN3(9{AzB%Aw!% zz~VNT|7u?_zSdXyH0?p&|4nHt{N0(9_{TRy4Ke@TBD!lfLPN7p&i zsNCj&?=$ms6Mn7$ovEJX3>n-rOa$x|BWGBtkL=U&K%cC|zvA;~D&tu5*D}y5A_!3m z>@*2+t{i5?-U9Yku_!a#^boA|PE#uRdY;~8On{^f@W=-5esFw66TV){io?V7RUoN7 zWxWAIyG;$XM4vxcHUZKLYs1II%&!rw-p|Gj0=qBjT-$n)pW=ATJ%#kyg3%ETkpIC zrgoNdEu8M15wwW2BI`Z`3?cQ(`46B%H(Wa>nfY_VIefTM1hEYEWPUwU50u5eDzt(A zrYqlRi(3~82u1;-m!TXykY}}l0cNxIVvF9DISH}#6zCxMI5mjZV{((3P%pTO?Dmkq z=^X~*?&KzaQ}&)Gu&c^NkEd7rcV1t6o(x`uOifL49}bO|cWp;2%XWMtU3EuaZ#M%H zU1;FW?sqo6_v|pP?s>ooy2}q#<*n6bi&O0IQZls52jjfWZncjX$n!<+>lDotlxSHx z2g9(F#NLol>K)#N-w^+pn=PwWBBsq@=k5;?X#uzq=3UW6eT^R_436|(i zeM>z#cTh~7b2^kk)J9;SvF}03AJMhqM43a9*_UrYU9$S4B(4OCcGVO2;DdZS0-u{+ z09FNN>fZ(SSFXZ{(XGv#9)G}P(t&h8l4!F)gQ>Ek^*ZL3u5RkWOUsWD-kj}N)%KpI zYLPZCF>A@e(w%oUYd2-YmSW3Qs{At0=%PP;M0ad{Q9AoZG}z81b5FNmb00YR{qlhS zTWs|V-30G1gmIjrFkr8UYsSD1_}c4Z6Te8oezfZe%uATy(C9K2QyJgj{-B@q3M9G= z^)u>dJu&{C6pg8KFz}tSw#~YJ(oy>P5^B)=Y%OYSN}NkPtx;-5;7dl5QHHf15MqC> zYaj+FPX6*JLD;@c%*s>3qHqSRyRSr7$a|?O^EWkqn8fbY(x=s8pT*mY9GjU~7CQZC zzl~fdTi1bWH8in#R9FPWE_rs(Kf@M`p;=GQQ8NSi;6!3gI^B-7i*ZUAtPS_3GYQY& zfc<5Ns&seMK=Ae0rGf;}-IH?zdlq;ai-0{z^>BYSi#q&uRv=CJUUr@h^}gwjI(>@@ zA(X^rxsfZTxUB38`j=g{OerNLc=F?C3VkD%kYba(-iI7byLhN9@L-_^-%s1T7W%va zr%*m8+8U?y2!zIySuBfOBYRRVoq3K-W4&idK7H!}y!q)mh&t)C^^N+TUsbIoMlL8q z6O#<;Gh3|=X|p#W))7kJQBCG)juDA|7_n+X+R7mI3X}5Cu&_cL8&jSy_SUcsm8f4q z?>8li_^a`KEOR;guzcx>&-~@;YYX(Jc*r_C8DojpFOCEiaO?oFrtW*~%T>qCwFhom z6as(^h4hl5UJf+L(^3?*hk&qnH=@Ugf3$*KQC^GO#40-{y(nEnsPz^2EPx@fNvn(7 zc|q6z0ZM%dRI@Tq<6V!PaZ|#Fp4UYt+G}}l?^*m-N+Qqz(Ss#K7hL&)b(_nvH+`oJ z!{YpmwNrr#!c>=~3>@Yozo=R7ytNm56<-FG_8~;MNz1#P(nuRb)IdE1q-?C@bCdap z%pr}Tt&$R9x~4eQ3%TA;^Oht{c9`Vl@bj!N%CWkGnriQe?)NgHgSs4}tD2xmMP-Z2AsrlF zplqq>isP9-oW-uAi6`kH}0`n7Bzx~!+DUD{pC(em09k2Heuv)fwWisC0zXf%Q z+>}=>G^M0@EwL|`6l7XMg~*BRin&z^)+}Le;$mK!@-^+&W);=7X99Fe*Pz7f~so)Cq!R&cQ)NdEbSA*B*(Up+-9lLayZ)+4piP)7_?FN0bW2XUsJ}1@rEmox9&T8%wEpvC5>hK7S0cE zn6kX%ow@Yuxm@U#gfl#C_8uFLg_b>84k?g^udB>L0mZ4jf78@CBeCQ=RvpOLR$s{Z zRj(33c+>nMJ8@+Jj~8*Z2B>DaT5ObRR-C?*xprk_^~c-z>e5%3CV9OGwf3N z-!GGvc!Qqj7WE(IT3d4|by4AGot1PBAjlCTjBIcb7L2=cN-f?&SKM6!wP$8IUT*A9 zxoVMB&iA^rbG^I2_S{W=ZE{LmpN0Pnn$#QmR`4@|l9oNL!k1km65ST-qkwsL>NiXp zb3n2$wu@9QhAaI774dPU$PK<>-c354XLLrZEM*~VJHCwyCQ4_@)CycRRg3aauHcM! zi9Cns6%JW6O456dklC02VNoBEvKzX9tx}4XkyQ z+?&OqqjByPc0p19=GdsUx$J&;q@52tr2{4z)q@%~&$Ax9>?i+8E-V|k|DI#55ynh&t=9s*4z|^2xdU4>$>j1f8Hh(ottg< zunRf|uvO@fbLzjg$D8Xp>u~_))cZ<{7C53v-tF!BnZR>G4cU2!p`EBiE#;rtp`-Tl zb34_)Mmky??&E*&s;0PIWUle3Mh(b9^eT;sElo+g+W6j{8ABK8F8R3fyK<3#MGjN1qGjxT*)lSqxQU}Lj7(168*s)&>m)eC!6ba9&GF&$ec%`fuc^Tk7FEuL@juxad8ZGM##ADvf5*uONT1?4W zA%c;V-K|n-)>0oAkjv|sUJ;o1djHdc+(`AF8>NG!i4-8*xt>e2#kARbj-PE$cjCGWis7r=n@5|IAogy4^d z>@D@2tPM;7r)kag>|w=e>0XJAj8cn#q^^=5n;4~%m>d-!mZX=KlBNAZPbFRanVynL zT5?DnyvoS|S@JZFSw8%%8acf22V>TQ3^2UsqP&3e`2dL?kbdD=|Ccg2*c;Hfo7w*V z$q^PFcV5f{`&5=uE_GlgfDFul^e-C+evsw=`WViCQF{Y-T_rX^X)geY43K_bd%FLR zN}vB!SD3#d8l0&s{1nju(BuDAvc8%1577%A-p*A}f4%0vi#z<6;w;Vd|0?e9U!{pF{v;IOuYVP1WM%8<_Jdf6+6qz(Dd^+? z=l?(mfCMmv0!fJr3d<-6I}FOw(<=85NXdMpmRbK%1Wl2j;n09g(!z@TwBj-%Kd=il z6r`H!kYOJhWDOua`|)QEZdQPU)D{jC6aUmwacttD;Rl{J5zeP}x1N3KKKra+NvK+% zTgXC7OO93w9a^T6%KrvGlQTvONobnQ(c;G@_u-*5-PTBKfE9ZXa7Y&r-QZCufVtMn z%)#MdH*T83xOEpHoabRXka&w(21;yqs41mmeNnad?Q2VU)=-u`Qr+(duPY zH!@8K1GDbs-`kl7?ef13GaY30zlC_EqnpEdouz3+NN1)oLEXzBjV@0!?a>lYn>3vL9?d)}e%@VCcw59simA7}s9W5}W~UCn&iuUCGRvAeh{OIlzqH+4 zDE4`(z)uvR^|3Z5m-@BN;@#s4Q0OfDn=iX$>tYF>>EI7%J6DH>An4hJje3sS330}< zrQ9}W5AeUmdMS{I?F#Iu%M~!Hdo(&@rl97y z3^eSRkP-Y{68J|Q?*!^-h3>SW%^h1fHrGV7G$afQvIY`R!MXVSfnPOm)Ir2}bvY#> z%CH#4bMKZHlf$*Igsj68N$xhyM#W?}M?2^&$|>rpG!DdioGun)Mr=^l>KrELMQofHyU;27bU8_2 z5E!7p^~T@)XJrNh0yL$ct_QWg8w3JqC@;-Dg0JQ`LL48mPK#ZdrK#Zg8FiIyFfU0~3q=)|K@yY|-{#^K9 zfWLYLL1DlM^+#ErJ}-<%4&ZJF0RIK*@1F5do`;xA>#4E8Zvj6q0-W^%>@@q~A^`m5 zUm$>kgFn{mfy15&LAe0P%@1H<{XhW%+6T1Ef8p4hJ;nHZs9X37$j%MG{45R#!07WY z7&CkQr<{`@xfKTh!v;_ZoS($OfcRIAy`F{9QxHErwKNp~!USkrKZCjeefGZyWDjuI z@f0+{v2XSoAW0%1{ruv|04ne=AV(vBM}z;WTuzzq&^Vy<5Wv^tA&$@Ewft+8yfD9z z^wTEvv^oFWg!TZ-a=#GjAwJMU&HmBbr;wj(Mg&lie}PyUndn*mq#X~f2&a48b`u^5 zsFnQhvD{u8zi7#@OxJ$?G_S}dY5fXBrP@HIm5NCn(Q5dA?$BU?*a z#$QuQW(;jC0F8qZ&^SnbqUr-iV85-om6_wO*t!80iJ!6`8rG^3u5A=RX7T@e3Ic%Qe#L2h9)v7LLrA6qG^KvPz>fAO zWSYbukbl+R(#*gJurU6s`VUvam4gFjCQ`vq+ds1GAJ8U%_Rsw5_7C4n<}VF+s!9N% ze|`p9-hZIF1IEq267;KJ?Yl&PqGAFbz|V@h|N0L|gMU}leyS~wx9ETw3ZQ{L3=1Bw z!Pq}gAF9vvD@j{c&SdWZZ)zOS1yeo(0e88De_&ev=9%t96hTk`R6ob)DR#U1e}iSB zWBjGGPhu-R3amQy2kieuTKrwd|MPdKarR%C|A{X5^C;wLe7Q&IPX0jpG1}Zy6@40B z?U5=z|9knK23vbde(G8MkzBaB2;$P*>|J@4n;eowhicg{U>g~@-<{o_8mr$s$oZGSAvlm7Qb z{k``7l=pOb=8>1e`g`8rO7hQQ&5zt)*?=FpQ5?VI{@7*yXc2x2erni#1S50)@4^4E zcs_+cwbVYs)Bgy6u-iW6J+;F=@{qXxBuS~L!*>Zl&_K$(~$Cvvn8|!2CX8>c#|CIWJ#r1)J5Bj(1 z>Ax+Dn12BPCK906zFIs#5Pq^Vg8yx2d}3pilLQA?Q682%_<))L6LTfr2hRTkF(urR diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/truffleruby2.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/truffleruby2.jar deleted file mode 100644 index a76c2649225589e34514ea252199948229503747..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86813 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/trufflerubyRO.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/commands/trufflerubyRO.jar deleted file mode 100644 index 9120af48c3173f36427a7053b6fbb4ff42135500..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86851 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 skL3ThCjLkc^#3XGqV=!y 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 MHe7V?bb~", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} -component_catalog="https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties|{ee=Enterprise Edition}gds://oca.opensource.oracle.com/gds/meta-data.json|https://www.graalvm.org/component-catalog/graal-updater-ee-component-catalog-java8.properties" - -component_catalog_url=https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties -component_catalog_label=GitHub CE 8 Components -component_catalog_editionLabel=GraalVM CE - -component_catalog_2_url=https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java11.properties -component_catalog_2_label=GitHub CE 11 Components - -ee_component_catalog_10_url=gds://oca.opensource.oracle.com/gds/meta-data.json -ee_component_catalog_10_label=GDS Component distribution -ee_component_catalog_editionLabel=GraalVM EE - -ee_component_catalog_15_url=https://whenever.acme.org/ee-extras.properties -ee_component_catalog_15_label=Some experimental components - -ee_component_catalog_13_url=https://www.graalvm.org/component-catalog/graal-updater-ee-component-catalog-java8.properties -ee_component_catalog_13_label=Github distribution -ee_component_catalog_13_paramX=valueY diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/GraalChannelBaseTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/GraalChannelBaseTest.java deleted file mode 100644 index 40f9ada72322..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/GraalChannelBaseTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds; - -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.FileDownloader; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import org.junit.Rule; -import org.junit.Test; -import java.io.IOException; - -/** - * - * @author sdedic - */ -public class GraalChannelBaseTest extends CommandTestBase { - @Rule public ProxyResource proxyResource = new ProxyResource(); - - GraalChannelBase channel; - - @Override - public void setUp() throws Exception { - super.setUp(); - channel = new GraalChannelBase(this, this.withBundle(org.graalvm.component.installer.gds.rest.GDSChannel.class), this.getLocalRegistry()) { - @Override - public FileDownloader configureDownloader(ComponentInfo info, FileDownloader dn) { - return dn; - } - - @Override - protected ComponentStorage loadStorage() throws IOException { - return null; - } - }; -// storage.graalInfo.put(CommonConstants.CAP_EDITION, "ee"); -// -// storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "linux"); -// storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "22.1.0"); -// storage.graalInfo.put(CAP_JAVA_VERSION, "11"); - } - - @Test - public void testThrowEmptyStorage() throws Exception { - try { - channel.throwEmptyStorage(); - fail("Exception expected"); - } catch (IncompatibleException ex) { - // ok - } - ComponentStorage chStorage = channel.throwEmptyStorage(); - assertNotNull("Stub storage expected for 2nd time", chStorage); - - assertEquals(0, chStorage.listComponentIDs().size()); - assertEquals(0, chStorage.loadComponentMetadata("org.graalvm").size()); - assertEquals(0, chStorage.loadGraalVersionInfo().size()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-19.3.2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-19.3.2.properties deleted file mode 100644 index 2cd8eeb666a5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-19.3.2.properties +++ /dev/null @@ -1,77 +0,0 @@ -# 19.3.2 Release -org.graalvm.19.3.2_macos_amd64=GraalVM 19.3.2 macos/amd64 -org.graalvm.19.3.2_linux_amd64=GraalVM 19.3.2 linux/amd64 - -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/llvm-toolchain-installable-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-hash=bd236156ba4d47848236a317552d3e8ac11d1f33ee0843f87f65c5f28d59921c -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.19.3.2_macos_amd64.org.graalvm.llvm_toolchain-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/llvm-toolchain-installable-java8-linux-amd64-19.3.2.jar -#Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-hash=c48fa0205b8ef891d11d8f3687851a921ca3a4a9928d5072c8f253cf794eb9de -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.19.3.2_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.native_image=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/native-image-installable-svm-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.native_image-hash=c69e039f1f2896881e627df97149436fb587a52a1f2bb469ee094fa5f467f69b -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.19.3.2_macos_amd64.org.graalvm.native_image-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.native_image=test://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.2/native-image-installable-svm-java8-linux-amd64-19.3.2.jar -#Component.19.3.2_linux_amd64.org.graalvm.native_image-hash=30b59f3eb84c91d742822ea4f2647e882cd04ed68d97954d60cfb7f84dc71719 -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.19.3.2_linux_amd64.org.graalvm.native_image-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.python=test://github.com/graalvm/graalpython/releases/download/vm-19.3.2/python-installable-svm-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.python-hash=1e95d88cac02694dfad97b4da361282e1b8e427732850d3d5db93ac8fddc8d72 -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.19.3.2_macos_amd64.org.graalvm.python-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.19.3.2_linux_amd64.org.graalvm.python=test://github.com/graalvm/graalpython/releases/download/vm-19.3.2/python-installable-svm-java8-linux-amd64-19.3.2.jar -Component.19.3.2_linux_amd64.org.graalvm.python-hash=0b0404691263ab9ce7c49ea633e82836be80b2fc4caa155b72d1627d1fd48add -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.19.3.2_linux_amd64.org.graalvm.python-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.python-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python -Component.19.3.2_macos_amd64.org.graalvm.r=test://github.com/oracle/fastr/releases/download/vm-19.3.2/r-installable-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.r-hash=d137b2558a96cc2040c334c3ca42ad4670299de97903d34e11744882f0b0af87 -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.19.3.2_macos_amd64.org.graalvm.r-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.19.3.2_linux_amd64.org.graalvm.r=test://github.com/oracle/fastr/releases/download/vm-19.3.2/r-installable-java8-linux-amd64-19.3.2.jar -Component.19.3.2_linux_amd64.org.graalvm.r-hash=9bc18e48c1cd697b37940d9fecf6f0cef0c2c66ea466834e359c5aa17cfdf286 -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.19.3.2_linux_amd64.org.graalvm.r-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R -Component.19.3.2_macos_amd64.org.graalvm.ruby=test://github.com/oracle/truffleruby/releases/download/vm-19.3.2/ruby-installable-svm-java8-darwin-amd64-19.3.2.jar -Component.19.3.2_macos_amd64.org.graalvm.ruby-hash=c25515aa7a3ed8937b062887bc6377580351831b12fab87733b14f0388a2a56c -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=macos)(os_arch=amd64)(java_version=8))" -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.19.3.2_macos_amd64.org.graalvm.ruby-Bundle-Version=19.3.2 -Component.19.3.2_macos_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby -Component.19.3.2_linux_amd64.org.graalvm.ruby=test://github.com/oracle/truffleruby/releases/download/vm-19.3.2/ruby-installable-svm-java8-linux-amd64-19.3.2.jar -Component.19.3.2_linux_amd64.org.graalvm.ruby-hash=ab0f4c915dade7772206f97589a5a94776cd597d7c4f6b6d8997fedc13cf0c47 -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.2)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.19.3.2_linux_amd64.org.graalvm.ruby-Bundle-Version=19.3.2 -Component.19.3.2_linux_amd64.org.graalvm.ruby-Require-Bundle=org.graalvm.llvm-toolchain -Component.19.3.2_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-20.3.0.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-20.3.0.properties deleted file mode 100644 index 55f64c21b12c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/catalog-20.3.0.properties +++ /dev/null @@ -1,15 +0,0 @@ -# 20.3.0 Release -org.graalvm.20.3.0_macos_amd64=GraalVM 20.3.0 macos/amd64 -org.graalvm.20.3.0_linux_amd64=GraalVM 20.3.0 linux/amd64 - -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain=llvm-deps-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Name=LLVM.org toolchain -Component.20.3.0_linux_amd64.org.graalvm.llvm_toolchain-Bundle-Version=20.3.0 - -Component.20.3.0_linux_amd64.org.graalvm.native_image=native-image-deps-20.3.0.jar -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=20.3.0)(os_name=linux)(os_arch=amd64)(java_version=8))" -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-Name=Native Image -Component.20.3.0_linux_amd64.org.graalvm.native_image-Bundle-Version=20.3.0 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/insttest.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/insttest.json deleted file mode 100644 index 1cadcf22f200..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/insttest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "Releases": { - "20.3.0-ee-jdk8": { - "name": "GraalVM Enterprise Edition 20.3.0 on jdk8", - "license": "test://acme.org/GRAALVM_EE_JAVA8_20.3.0/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "catalog": "catalog-20.3.0.properties", - "edition": "ee", - "java": "jdk8", - "version": "20.3.0", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "test://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/license.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/license.txt deleted file mode 100644 index fcf20ef4d3d8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/license.txt +++ /dev/null @@ -1 +0,0 @@ -License -- dummy test license. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/llvm-deps-20.3.0.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/llvm-deps-20.3.0.jar deleted file mode 100644 index 9c3f8d790274ad0288954faf4dde586142cbe013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 478 zcmWIWW@Zs#VBp|ju*tX_zyJhHAOZ+D8CV#6T|*poJ^kGD|D9rBU}gw_D;8bT5x6yz zQ*Z}RAqyh|g9w8RLb0!-pQoE^aEP9-TWAO;1M|yA=i?s$acKoN10%}|W}p@jk=p0T z-Q*zB^8R1fQRf$l;ww80_J~|@b>`Z0%G>;I#k*^}y8ivv(e2P<&cAo&c#iZ;<>l@x zcK9DM=$vth)zB+3tZBlvvOn{GzgiTK5?pX%gA;Q?w4qGPKT)A|*$bEWKa-0#c%MA~ z$6~=*?;r4qHy-+8zlL`wmr2a;#|>1k)s-@3EE*}7_xfLmlysQ7 ze%iX?X0d%sx4ym==FYDlCUh|(F@AxO30rQ>CiXQuzp?~)Gct()eT*y6z@Y~xP=XMo wRgM{=6*CAWz?y)e$QC~{Z}hgaHgbvGMpKzmL8IQ zVTK3uysVHV3mpuz=f*DXpQia*>6&QZLxvsKF7E#!7wdUVrAWa2u*Sa=(R)Il6!3*x z2u;qf^9Zg~`u1Yd7V$65el}NhwQ47~^c+4gjs0`ZM5CFn{>2?keJ)aBC)awAHS33* z@1YIq@3MX-y$#Pw-l=(`YAfS&;hhY6fh9{rZh!o4UdQ)z?bA0rDMy$CycwB9fL_NH zdf;G$6DVN`(kjOc(TW+C5@1chU}b1%)CH1ottcVO3JF=XPz~^AWdmtv0>Y_4+6H6{ F0|4~jlEeT2 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badJava.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badJava.json deleted file mode 100644 index 5fed0e3155b6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badJava.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdx11", - "version": "19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - } -} - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badVersion.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badVersion.json deleted file mode 100644 index be5841c950a5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-badVersion.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "https://acme.org/gds/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "a19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-invalid-catalog.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-invalid-catalog.json deleted file mode 100644 index 5f9a8fb8bbe0..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-invalid-catalog.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.2", - "catalog": "!!!-19.3.2.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-missingEdition.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-missingEdition.json deleted file mode 100644 index 73b86df44445..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-missingEdition.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "java": "jdk8", - "version": "19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-no-bases.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-no-bases.json deleted file mode 100644 index d0615b8d070e..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/rel-no-bases.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.2", - "catalog": "catalog-19.3.2.properties" -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases-mix.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases-mix.json deleted file mode 100644 index 9bf12ee054d2..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases-mix.json +++ /dev/null @@ -1,171 +0,0 @@ -{ - "Releases": { - "19.3.3-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - } - }, - "19.3.3-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk11", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk11", - "version": "19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/19_3_3_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "x86_64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-windows-amd64-19.3.3.zip" - } - } - }, - "19.3.2-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.2", - "catalog": "https://oca.opensource.oracle.com/olds/GRAALVM_EE_JAVA8_19_3_2/19.3.2_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - } - }, - "19.3.2-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk11", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk11", - "version": "19.3.2", - "catalog": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/19.3.2_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "Linux", - "arch": "x86_64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-linux-amd64-19.3.2.tar.gz" - }, - "macos-amd64": { - "os": "macos", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "x86_64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-windows-amd64-19.3.2.zip" - } - } - }, - - "19.3.2-ce-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ce", - "java": "jdk8", - "version": "19.3.2", - "catalog": "https://oca.opensource.oracle.com/olds/GRAALVM_EE_JAVA8_19_3_2/19.3.2_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - } - }, - - "19.3.2-ee2-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee2", - "java": "jdk8", - "version": "19.3.2", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - } - }, - - "19.3.2-ee3-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee3", - "java": "jdk8", - "version": "19.3.2", - "catalog": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/19.3.2_EE_Java8_component-catalog.properties" - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases.json deleted file mode 100644 index d9eb382eb637..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "Releases": { - "19.3.3-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "test://acme.org/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "catalog": "test://acme.org/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": "test://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz", - "darwin-amd64": "test://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz", - "windows-amd64": "test://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - }, - "19.3.3-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk11", - "license": "test://acme.org/GRAALVM_EE_JAVA11_19_3_3/license.txt", - "catalog": "test://acme.org/GRAALVM_EE_JAVA11_19_3_3/19_3_3_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": "test://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-linux-amd64-19.3.3.tar.gz", - "darwin-amd64": "test://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-darwin-amd64-19.3.3.tar.gz", - "windows-amd64": "test://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-windows-amd64-19.3.3.zip" - } - }, - "19.3.2-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "test://acme.org/GRAALVM_EE_JAVA8_19_3_2/license.txt", - "catalog": "catalog-19.3.2.properties", - "base": { - "linux-amd64": "test://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz", - "darwin-amd64": "test://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz", - "windows-amd64": "test://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - }, - "19.3.2-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk11", - "license": "test://acme.org/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "catalog": "test://acme.org/GRAALVM_EE_JAVA11_19_3_2/19.3.2_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": "test://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-linux-amd64-19.3.2.tar.gz", - "darwin-amd64": "test://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-darwin-amd64-19.3.2.tar.gz", - "windows-amd64": "test://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-windows-amd64-19.3.2.zip" - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases2.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases2.json deleted file mode 100644 index 0d5a39806353..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/data/releases2.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "Releases": { - "19.3.3-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/19_3_3_EE_Java8_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_3/graalvm-ee-java8-windows-amd64-19.3.3.zip" - } - } - }, - "19.3.3-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.3 on jdk11", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk11", - "version": "19.3.3", - "catalog": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/19_3_3_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-linux-amd64-19.3.3.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-darwin-amd64-19.3.3.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_3/graalvm-ee-java11-windows-amd64-19.3.3.zip" - } - } - }, - "19.3.2-ee-jdk8": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk8", - "license": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk8", - "version": "19.3.2", - "catalog": "catalog-19.3.2.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA8_19_3_2/graalvm-ee-java8-windows-amd64-19.3.2.zip" - } - } - }, - "19.3.2-ee-jdk11": { - "name": "GraalVM Enterprise Edition 19.3.2 on jdk11", - "license": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/license.txt", - "licenseLabel": "GraalVM Enterprise Edition License", - "edition": "ee", - "java": "jdk11", - "version": "19.3.2", - "catalog": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/19.3.2_EE_Java11_component-catalog.properties", - "base": { - "linux-amd64": { - "os": "linux", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-linux-amd64-19.3.2.tar.gz" - }, - "darwin-amd64": { - "os": "darwin", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-darwin-amd64-19.3.2.tar.gz" - }, - "windows-amd64": { - "os": "windows", - "arch": "amd64", - "url": "https://acme.org/GRAALVM_EE_JAVA11_19_3_2/graalvm-ee-java11-windows-amd64-19.3.2.zip" - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/ArtifactParserTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/ArtifactParserTest.java deleted file mode 100644 index e97b98c3d258..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/ArtifactParserTest.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import java.util.Arrays; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.model.StabilityLevel; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONException; -import org.graalvm.shadowed.org.json.JSONObject; -import org.junit.Test; -import java.util.Collections; -import java.util.Locale; -import java.util.Map; - -/** - * - * @author odouda - */ -public class ArtifactParserTest extends TestBase { - static final String MOCK_URL = "https://mock.url/"; - static final String JSON_VAL_ID = "mockProductId"; - static final String JSON_KEY_ID = "id"; - static final String JSON_KEY_CHECKSUM = "checksum"; - static final String JSON_VAL_CHECKSUM = "mockChecksum"; - static final String JSON_KEY_METADATA = "metadata"; - static final String JSON_KEY_DISP_NAME = "displayName"; - static final String JSON_VAL_DISP_NAME = "mockDisplayName"; - static final String JSON_KEY_LIC_ID = "licenseId"; - static final String JSON_VAL_LIC_ID = "mockLicenseId"; - static final String JSON_KEY_LIC_NAME = "licenseName"; - static final String JSON_VAL_LIC_NAME = "mockLicenseName"; - static final String JSON_KEY_IMPL_ACC = "isLicenseImplicitlyAccepted"; - static final String JSON_META_KEY = "key"; - static final String JSON_META_VAL = "value"; - static final String JSON_META_KEY_ARCH = "arch"; - static final String JSON_META_VAL_ARCH = "fakeArch"; - static final String JSON_META_KEY_OS = "os"; - static final String JSON_META_VAL_OS = "fakeOS"; - static final String JSON_VAL_DISP_NAME2 = JSON_VAL_DISP_NAME + " " + JSON_META_VAL_OS; - static final String JSON_META_KEY_JAVA = "java"; - static final String JSON_META_VAL_JAVA = "5"; - static final String JSON_META_KEY_VERSION = "version"; - static final String JSON_META_VAL_VERSION = "18.1.3"; - static final String JSON_META_KEY_EDITION = "edition"; - static final String JSON_META_VAL_EDITION = "ee"; - static final String JSON_META_KEY_STABILITY_LEVEL = "stabilityLevel"; - static final String JSON_META_KEY_STABILITY = "stability"; - static final String JSON_META_VAL_STAB_EXPERIMENTAL = StabilityLevel.Experimental.toString(); - static final String JSON_META_VAL_STAB_SUPPORTED = StabilityLevel.Supported.toString(); - static final String JSON_META_KEY_SYMBOLIC_NAME = "symbolicName"; - static final String JSON_META_VAL_SYMBOLIC_NAME = "org.graalvm.llvm-toolchain"; - static final String JSON_META_KEY_DEPENDENCY = "requireBundle"; - static final String JSON_META_KEY_REQUIRED = "requiredCapabilities"; - static final String REQ_VER = "graalvm_version"; - static final String REQ_OS = "os_name"; - static final String REQ_ARCH = "os_arch"; - static final String REQ_JAVA = "java_version"; - static final String JSON_META_VAL_REQUIRED = "org.graalvm; filter:=\"(&(" + REQ_VER + "=" + JSON_META_VAL_VERSION + ")(" + REQ_OS + "=" + JSON_META_VAL_OS + ")(" + REQ_ARCH + "=" + - JSON_META_VAL_ARCH + ")(" + REQ_JAVA + "=" + JSON_META_VAL_JAVA + "))\""; - static final String JSON_META_KEY_POLYGLOT = "polyglot"; - static final String JSON_META_KEY_WORK_DIR = "workingDirectories"; - static final String JSON_META_VAL_WORK_DIR = "languages/python"; - - @SuppressWarnings("this-escape") GDSRESTConnector conn = new GDSRESTConnector(MOCK_URL, this, JSON_VAL_ID, Version.fromString(JSON_META_VAL_VERSION)); - - @Test - public void testConstruct() { - ArtifactParser ap = null; - try { - ap = new ArtifactParser(null); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - assertEquals("Parsed Artifact JSON cannot be null.", ex.getMessage()); - // expected - } - JSONObject jo = new JSONObject(); - try { - ap = new ArtifactParser(jo); - fail("JSONException expected."); - } catch (JSONException ex) { - tstJsonExc(ex, JSON_KEY_ID); - // expected - } - jo.put(JSON_KEY_ID, JSON_VAL_ID); - try { - ap = new ArtifactParser(jo); - fail("JSONException expected."); - } catch (JSONException ex) { - tstJsonExc(ex, JSON_KEY_CHECKSUM); - // expected - } - jo.put(JSON_KEY_CHECKSUM, JSON_VAL_CHECKSUM); - try { - ap = new ArtifactParser(jo); - fail("JSONException expected."); - } catch (JSONException ex) { - tstJsonExc(ex, JSON_KEY_METADATA); - // expected - } - JSONArray meta = new JSONArray(); - jo.put(JSON_KEY_METADATA, meta); - try { - ap = new ArtifactParser(jo); - fail("JSONException expected."); - } catch (JSONException ex) { - tstJsonExc(ex, JSON_KEY_DISP_NAME); - // expected - } - jo.put(JSON_KEY_DISP_NAME, JSON_VAL_DISP_NAME); - try { - ap = new ArtifactParser(jo); - fail("StringIndexOutOfBoundsException expected."); - } catch (StringIndexOutOfBoundsException ex) { - assertEquals(makeSubstringExceptionMessage(0, -1, 15), ex.getMessage()); - // expected - } - jo.put(JSON_KEY_DISP_NAME, JSON_VAL_DISP_NAME + SystemUtils.OS.get().getName()); - try { - ap = new ArtifactParser(jo); - fail("JSONException expected."); - } catch (JSONException ex) { - tstJsonExc(ex, JSON_KEY_LIC_ID); - // expected - } - jo.put(JSON_KEY_LIC_ID, JSON_VAL_LIC_ID); - try { - ap = new ArtifactParser(jo); - fail("JSONException expected."); - } catch (JSONException ex) { - tstJsonExc(ex, JSON_KEY_LIC_NAME); - // expected - } - jo.put(JSON_KEY_LIC_NAME, JSON_VAL_LIC_NAME); - ap = new ArtifactParser(jo); - assertEquals(null, ap.getLabel()); - assertEquals(SystemUtils.ARCH.get().getName(), ap.getArch()); - assertEquals(SystemUtils.OS.get().getName(), ap.getOs()); - assertEquals(SystemUtils.getJavaMajorVersion() + "", ap.getJava()); - assertEquals(null, ap.getVersion()); - assertEquals(null, ap.getEdition()); - setMeta(meta, JSON_META_KEY_ARCH, JSON_META_VAL_ARCH); - assertEquals(JSON_META_VAL_ARCH, ap.getArch()); - setMeta(meta, JSON_META_KEY_OS, JSON_META_VAL_OS); - assertEquals(JSON_META_VAL_OS, ap.getOs()); - setMeta(meta, JSON_META_KEY_JAVA, JSON_META_VAL_JAVA); - assertEquals(JSON_META_VAL_JAVA, ap.getJava()); - setMeta(meta, JSON_META_KEY_VERSION, JSON_META_VAL_VERSION); - assertEquals(JSON_META_VAL_VERSION, ap.getVersion()); - setMeta(meta, JSON_META_KEY_EDITION, JSON_META_VAL_EDITION); - assertEquals(JSON_META_VAL_EDITION, ap.getEdition()); - setMeta(meta, JSON_META_KEY_SYMBOLIC_NAME, JSON_META_VAL_SYMBOLIC_NAME); - assertEquals(JSON_META_VAL_SYMBOLIC_NAME, ap.getLabel()); - } - - private static String makeSubstringExceptionMessage(int start, int end, int length) { - String str = makeStringOfLength(length); - try { - str.substring(start, end); - } catch (StringIndexOutOfBoundsException ex) { - return ex.getMessage(); - } - return null; - } - - private static String makeStringOfLength(int length) { - char[] arr = new char[length]; - Arrays.fill(arr, 'a'); - return String.valueOf(arr); - } - - @Test - public void testAsComponentInfo() { - JSONObject jo = prepareJO(); - ArtifactParser ap = new ArtifactParser(jo); - ComponentInfo ci = ap.asComponentInfo(conn, this); - assertEquals(JSON_VAL_DISP_NAME, ci.getName()); - assertEquals(JSON_META_VAL_SYMBOLIC_NAME, ci.getId()); - assertEquals(Version.fromString(JSON_META_VAL_VERSION), ci.getVersion()); - assertEquals(JSON_META_VAL_VERSION, ci.getVersionString()); - assertArrayEquals(SystemUtils.toHashBytes(JSON_VAL_CHECKSUM), ci.getShaDigest()); - assertEquals(JSON_VAL_CHECKSUM, ci.getTag()); - assertEquals(conn.makeArtifactDownloadURL(JSON_VAL_ID), ci.getRemoteURL()); - assertEquals(conn.makeArtifactsURL(JSON_META_VAL_JAVA), ci.getOrigin()); - assertEquals(conn.makeLicenseURL(JSON_VAL_LIC_ID), ci.getLicensePath()); - assertEquals(JSON_VAL_LIC_NAME, ci.getLicenseType()); - assertEquals(DistributionType.OPTIONAL, ci.getDistributionType()); - assertEquals(Collections.singleton(JSON_META_VAL_WORK_DIR), ci.getWorkingDirectories()); - assertEquals(Map.of(REQ_ARCH, JSON_META_VAL_ARCH.toLowerCase(Locale.ENGLISH), - REQ_OS, JSON_META_VAL_OS.toLowerCase(Locale.ENGLISH), - REQ_JAVA, JSON_META_VAL_JAVA, - REQ_VER, JSON_META_VAL_VERSION), ci.getRequiredGraalValues()); - assertEquals(Collections.singleton(JSON_META_VAL_SYMBOLIC_NAME), ci.getDependencies()); - assertEquals(StabilityLevel.fromName(JSON_META_VAL_STAB_EXPERIMENTAL), ci.getStability()); - assertFalse(ci.isImplicitlyAccepted()); - setMeta(jo, JSON_META_KEY_STABILITY_LEVEL, JSON_META_VAL_STAB_SUPPORTED); - jo.put(JSON_KEY_IMPL_ACC, true); - ci = ap.asComponentInfo(conn, this); - assertEquals(StabilityLevel.fromName(JSON_META_VAL_STAB_SUPPORTED), ci.getStability()); - assertTrue(ci.isImplicitlyAccepted()); - } - - JSONObject setMeta(JSONObject jo, String key, String val) { - JSONArray meta = jo.optJSONArray(JSON_KEY_METADATA); - if (meta == null) { - meta = new JSONArray(); - jo.put(JSON_KEY_METADATA, meta); - } - return setMeta(meta, key, val); - } - - JSONObject setMeta(JSONArray meta, String key, String val) { - JSONObject o; - for (int i = 0; i < meta.length(); ++i) { - o = meta.getJSONObject(i); - if (key.equals(o.getString(JSON_META_KEY))) { - o.put(JSON_META_VAL, val); - return o; - } - } - o = new JSONObject(); - o.put(JSON_META_KEY, key); - o.put(JSON_META_VAL, val); - meta.put(o); - return o; - } - - JSONObject prepareJO() { - JSONObject jo = new JSONObject(); - jo.put(JSON_KEY_ID, JSON_VAL_ID); - jo.put(JSON_KEY_CHECKSUM, JSON_VAL_CHECKSUM); - jo.put(JSON_KEY_DISP_NAME, JSON_VAL_DISP_NAME2); - jo.put(JSON_KEY_LIC_ID, JSON_VAL_LIC_ID); - jo.put(JSON_KEY_LIC_NAME, JSON_VAL_LIC_NAME); - JSONArray meta = new JSONArray(); - jo.put(JSON_KEY_METADATA, meta); - setMeta(meta, JSON_META_KEY_SYMBOLIC_NAME, JSON_META_VAL_SYMBOLIC_NAME); - setMeta(meta, JSON_META_KEY_ARCH, JSON_META_VAL_ARCH); - setMeta(meta, JSON_META_KEY_OS, JSON_META_VAL_OS); - setMeta(meta, JSON_META_KEY_JAVA, JSON_META_VAL_JAVA); - setMeta(meta, JSON_META_KEY_VERSION, JSON_META_VAL_VERSION); - setMeta(meta, JSON_META_KEY_EDITION, JSON_META_VAL_EDITION); - setMeta(meta, JSON_META_KEY_REQUIRED, JSON_META_VAL_REQUIRED); - setMeta(meta, JSON_META_KEY_POLYGLOT, Boolean.toString(false)); - setMeta(meta, JSON_META_KEY_WORK_DIR, JSON_META_VAL_WORK_DIR); - setMeta(meta, JSON_META_KEY_DEPENDENCY, JSON_META_VAL_SYMBOLIC_NAME); - setMeta(meta, JSON_META_KEY_STABILITY, JSON_META_VAL_STAB_EXPERIMENTAL); - return jo; - } - - void tstJsonExc(JSONException ex, String key) { - assertEquals("JSONObject[\"" + key + "\"] not found.", ex.getMessage()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorageTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorageTest.java deleted file mode 100644 index b9fc8fe07625..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorageTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import static org.junit.Assert.assertEquals; -import org.junit.Test; -import java.io.IOException; -import java.net.URL; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * - * @author odouda - */ -@SuppressWarnings("this-escape") -public class GDSCatalogStorageTest extends CommandTestBase { - static final String MOCK_URL = "https://mock.url/"; - static final String ID1 = "id1"; - static final String ID2 = "id2"; - URL mockUrl; - - List infos = getComps(); - - @Override - public void setUp() throws Exception { - super.setUp(); - mockUrl = SystemUtils.toURL(MOCK_URL); - } - - @Test - public void test() throws IOException { - GDSCatalogStorage cs = getGDSCatalogStorage(); - HashMap> map = getMapComps(); - assertEquals(map, cs.getComponents()); - assertEquals(map.get(ID1), cs.loadComponentMetadata(ID1)); - assertEquals(map.get(ID2), cs.loadComponentMetadata(ID2)); - assertEquals(map.keySet(), cs.listComponentIDs()); - } - - private GDSCatalogStorage getGDSCatalogStorage() { - return new GDSCatalogStorage(localRegistry, this, mockUrl, infos); - } - - List getComps() { - return List.of(new ComponentInfo(ID1, "name11", Version.NO_VERSION), - new ComponentInfo(ID1, "name12", Version.NO_VERSION), - new ComponentInfo(ID2, "name21", Version.NO_VERSION), - new ComponentInfo(ID2, "name22", Version.NO_VERSION)); - } - - HashMap> getMapComps() { - HashMap> map = new HashMap<>(); - for (ComponentInfo c : infos) { - map.computeIfAbsent(c.getId(), id -> new HashSet<>()).add(c); - } - return map; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSChannelTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSChannelTest.java deleted file mode 100644 index d6c836c8d382..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSChannelTest.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.MemoryFeedback; -import java.nio.file.Path; -import java.util.Collection; -import java.util.List; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.CAP_JAVA_VERSION; -import static org.graalvm.component.installer.CommonConstants.RELEASE_GDS_PRODUCT_ID_KEY; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.Version; -import static org.graalvm.component.installer.gds.rest.GDSChannelTest.TestGDSChannel.MockGDSCatalogStorage.ID; -import org.graalvm.component.installer.MemoryFeedback.Case; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.remote.ProxyConnectionFactory.HttpConnectionException; -import org.graalvm.shadowed.org.json.JSONException; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import static java.nio.charset.StandardCharsets.UTF_8; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import static org.junit.Assert.assertFalse; - -/** - * - * @author odouda - */ -public class GDSChannelTest extends CommandTestBase { - private static final String MOCK_TOKEN = "MOCK_TOKEN"; - private static final String HEADER_DOWNLOAD_CONFIG = "x-download-token"; - @Rule public TestName name = new TestName(); - @Rule public ProxyResource proxyResource = new ProxyResource(); - - TestGDSChannel channel; - MemoryFeedback mf; - - @Override - public void setUp() throws Exception { - super.setUp(); - delegateFeedback(mf = new MemoryFeedback()); - - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ee"); - - storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "linux"); - storage.graalInfo.put(CommonConstants.CAP_OS_ARCH, "amd64"); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "22.1.0"); - storage.graalInfo.put(CommonConstants.RELEASE_GDS_PRODUCT_ID_KEY, "mockProductId"); - storage.graalInfo.put(CAP_JAVA_VERSION, "11"); - - refreshChannel(); - } - - @After - public void tearDown() { - assertTrue(name.getMethodName() + ": " + mf.toString(), mf.isEmpty()); - } - - private void refreshChannel() { - this.localRegistry = null; - channel = new TestGDSChannel(this, this, this.getLocalRegistry()); - } - - private void refreshChannel(Path p) throws MalformedURLException { - refreshChannel(); - channel.setIndexURL(p.toUri().toURL()); - } - - @Test - public void testWrongJson() throws Exception { - Path p = dataFile("../data/rel-no-bases.json"); - channel.setIndexURL(p.toUri().toURL()); - try { - channel.loadArtifacts(p, Collections.emptyList()); - fail("JSONexception expected."); - } catch (JSONException ex) { - // expected - } - } - - @Test - public void testNoUsableComponents() throws Exception { - Path p = dataFile("data/gdsreleases.json"); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "22.0.0"); - refreshChannel(p); - List infos = channel.loadArtifacts(p, Collections.emptyList()); - assertTrue(infos.isEmpty()); - } - - @Test - public void testFilterUpdates() throws Exception { - Path p = dataFile("data/gdsreleases.json"); - channel.setIndexURL(p.toUri().toURL()); - tstUpdates(p, 9, 18); - storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "macos"); - refreshChannel(p); - tstUpdates(p, 9, 18); - storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "windows"); - refreshChannel(p); - tstUpdates(p, 5, 10); - storage.graalInfo.put(CommonConstants.CAP_OS_ARCH, "aarch64"); - storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "linux"); - refreshChannel(p); - tstUpdates(p, 7, 14); - storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "macos"); - refreshChannel(p); - tstUpdates(p, 0, 0); - storage.graalInfo.put(CommonConstants.CAP_OS_NAME, "windows"); - refreshChannel(p); - tstUpdates(p, 0, 0); - } - - private void tstUpdates(Path p, int noUpdates, int allowedUpdates) throws IOException { - channel.setAllowUpdates(false); - checkArtifactsCount(p, noUpdates); - channel.setAllowUpdates(true); - checkArtifactsCount(p, allowedUpdates); - } - - private void checkArtifactsCount(Path p, int count) throws IOException { - List infos = channel.loadArtifacts(p, Collections.emptyList()); - assertEquals(infos.toString(), count, infos.size()); - } - - @Test - public void testFailOnNoURL() throws Exception { - Path p = dataFile("data/gdsreleases.json"); - try { - channel.loadArtifacts(p, Collections.emptyList()); - fail("Expected NPE from missing URL."); - } catch (NullPointerException ex) { - StackTraceElement stackTrace = ex.getStackTrace()[0]; - assertEquals("org.graalvm.component.installer.gds.rest.GDSChannelTest$TestGDSChannel", - stackTrace.getClassName()); - assertEquals("getConnector", stackTrace.getMethodName()); - } - } - - @Test - public void testLoadComponentStorage() throws Exception { - Path p = dataFile("data/gdsreleases.json"); - channel.setIndexURL(p.toUri().toURL()); - ComponentStorage store = channel.getStorage(); - assertTrue(mf.isEmpty()); - Collection cids = store.listComponentIDs(); - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - List infos = new ArrayList<>(); - for (String id : cids) { - infos.addAll(store.loadComponentMetadata(id)); - } - assertEquals(infos.toString(), 9, infos.size()); - } - - @Test - public void testInterceptDownloadException() throws Exception { - String mockUrlString = "http://some.mock.url/"; - URL url = SystemUtils.toURL(mockUrlString); - channel.setIndexURL(url); - IOException ioExc = new IOException("some Exception."); - FileDownloader fd = new FileDownloader("something", url, this); - try { - fd.download(); - } catch (Throwable t) { - } - mf.checkMem(Case.MSG, "MSG_Downloading", "something", url.getHost()); - channel.mockStorage(); - - channel.respErr = "{code:\"UnverifiedToken\"}"; - mf.nextInput("something"); - HttpConnectionException httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(channel.getConnector().makeArtifactDownloadURL(ID))); - IOException out = channel.interceptDownloadException(httpExc, fd); - assertSame(null, out); - mf.checkMem(Case.MSG, "ERR_InvalidToken", new Object[]{null}); - mf.checkMem(Case.INP, "something"); - - channel.respErr = "{code:\"InvalidToken\"}"; - channel.tokStore.setToken(MOCK_TOKEN); - mf.nextInput("token"); - httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(channel.getConnector().makeArtifactDownloadURL(ID))); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(null, out); - assertEquals("token", channel.tokStore.getToken()); - mf.checkMem(Case.MSG, "ERR_WrongToken", MOCK_TOKEN); - mf.checkMem(Case.MSG, "MSG_InputTokenEntry"); - mf.checkMem(Case.MSG, "PROMPT_InputTokenEntry"); - mf.checkMem(Case.INP, "token"); - mf.checkMem(Case.MSG, "MSG_ObtainedToken", "token"); - - mf.nextInput(null); - mf.nextInput("email@dot.com"); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(null, out); - assertEquals(GDSFileConnector.MOCK_TOKEN_NEW, channel.tokStore.getToken()); - mf.checkMem(Case.MSG, "ERR_WrongToken", "token"); - mf.checkMem(Case.MSG, "MSG_InputTokenEntry"); - mf.checkMem(Case.MSG, "PROMPT_InputTokenEntry"); - mf.checkMem(Case.INP, null); - mf.checkMem(Case.MSG, "MSG_EmailAddressEntry"); - mf.checkMem(Case.MSG, "PROMPT_EmailAddressEntry"); - mf.checkMem(Case.INP, "email@dot.com"); - mf.checkMem(Case.MSG, "MSG_ObtainedToken", GDSFileConnector.MOCK_TOKEN_NEW); - mf.checkMem(Case.MSG, "PROMPT_VerifyEmailAddressEntry", "email@dot.com"); - mf.checkMem(Case.INP, null); - - channel.respErr = "{code:\"InvalidLicenseAcceptance\"}"; - httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(channel.getConnector().makeArtifactDownloadURL(ID))); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(null, out); - mf.checkMem(Case.FRM, "MSG_YourEmail"); - mf.checkMem(Case.MSG, "PROMPT_VerifyEmailAddressEntry", "MSG_YourEmail"); - mf.checkMem(Case.INP, null); - - channel.respErr = "invalid json"; - httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(channel.getConnector().makeArtifactDownloadURL(ID))); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(ioExc, out); - - httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(channel.getConnector().makeArtifactDownloadURL(ID + 2))); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(ioExc, out); - - httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(url)); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(ioExc, out); - - channel.respCode = 300; - httpExc = new HttpConnectionException("my msg", ioExc, false, channel.new MockHttpURLConnection(channel.getConnector().makeArtifactDownloadURL(ID))); - out = channel.interceptDownloadException(httpExc, fd); - assertSame(ioExc, out); - - out = channel.interceptDownloadException(ioExc, fd); - assertSame(ioExc, out); - } - - @Test - public void testConfigureDownloader() throws MalformedURLException { - String mockUrlString = "http://some.mock.url/"; - URL url = SystemUtils.toURL(mockUrlString); - channel.setIndexURL(url); - channel.tokStore.setToken(MOCK_TOKEN); - FileDownloader fd = new FileDownloader("something", url, this); - ComponentInfo ci = new ComponentInfo("ID", "name", "1.0.0"); - channel.configureDownloader(ci, fd); - Map headers = fd.getRequestHeaders(); - assertEquals(MOCK_TOKEN, headers.get(HEADER_DOWNLOAD_CONFIG)); - assertEquals(3, headers.size()); - - fd = new FileDownloader("something", url, this); - ci.setImplicitlyAccepted(true); - channel.configureDownloader(ci, fd); - headers = fd.getRequestHeaders(); - assertEquals(null, headers.get(HEADER_DOWNLOAD_CONFIG)); - assertEquals(2, headers.size()); - } - - @Test - public void testNeedToken() { - ComponentInfo ci = new ComponentInfo("ID", "name", "1.0.0"); - assertTrue(channel.needToken(ci)); - - ci.setImplicitlyAccepted(true); - assertFalse(channel.needToken(ci)); - - ci.setImplicitlyAccepted(false); - assertTrue(channel.needToken(ci)); - } - - final class TestGDSChannel extends GDSChannel { - GDSRESTConnector conn = null; - String respErr = "Mock error response."; - int respCode = 401; - TestGDSTokenStorage tokStore; - - TestGDSChannel(CommandInput aInput, Feedback aFeedback, ComponentRegistry aRegistry) { - super(aInput, aFeedback, aRegistry); - setTokenStorage(tokStore = new TestGDSTokenStorage(aFeedback, aInput) { - @Override - public void save() throws IOException { - } - }); - } - - @Override - GDSRESTConnector getConnector() { - return conn == null ? conn = new GDSFileConnector( - channel.getIndexURL().toString(), - GDSChannelTest.this, - getLocalRegistry().getGraalCapabilities() - .get(RELEASE_GDS_PRODUCT_ID_KEY), - getLocalRegistry().getGraalVersion()) : conn; - } - - public void mockStorage() { - storage = new MockGDSCatalogStorage(localRegistry, fb, getIndexURL(), Collections.emptyList()); - } - - final class MockGDSCatalogStorage extends GDSCatalogStorage { - static final String ID = "id"; - final ComponentInfo ci = new ComponentInfo(ID, ID, Version.NO_VERSION); - - MockGDSCatalogStorage(ComponentRegistry localRegistry, Feedback feedback, URL baseURL, Collection artifacts) { - super(localRegistry, feedback, baseURL, artifacts); - ci.setRemoteURL(getConnector().makeArtifactDownloadURL(ID)); - ci.setLicensePath(getConnector().makeLicenseURL(ID)); - } - - @Override - public Set listComponentIDs() throws IOException { - return Collections.singleton(ID); - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - assertSame(ID, id); - return Collections.singleton(ci); - } - } - - final class MockHttpURLConnection extends HttpURLConnection { - MockHttpURLConnection(URL url) { - super(url); - } - - @Override - public void disconnect() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean usingProxy() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void connect() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public InputStream getErrorStream() { - return new ByteArrayInputStream(respErr.getBytes(UTF_8)); - } - - @Override - public int getResponseCode() throws IOException { - return respCode; - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSFileConnector.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSFileConnector.java deleted file mode 100644 index 98e797a3f9ce..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSFileConnector.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.remote.FileDownloader; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * - * @author odouda - */ -public class GDSFileConnector extends GDSRESTConnector { - public GDSFileConnector(String baseURL, Feedback feedback, String productId, Version gvmVersion) { - super(baseURL, feedback, productId, gvmVersion); - } - - @Override - protected Map> getParams() { - return Collections.emptyMap(); - } - - @Override - protected FileDownloader obtain(String endpoint) { - return super.obtain(""); - } - - static final String MOCK_TOKEN_NEW = "newMockToken"; - String[] verEmInps; - - @Override - public String sendVerificationEmail(String email, String licAddr, String oldToken) { - verEmInps = new String[]{email, licAddr, oldToken}; - return oldToken == null ? MOCK_TOKEN_NEW : oldToken; - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSRESTConnectorTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSRESTConnectorTest.java deleted file mode 100644 index 87948b3d5bb2..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSRESTConnectorTest.java +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.MemoryFeedback; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.URLConnectionFactory; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.gds.rest.GDSRESTConnector.GDSRequester; -import org.graalvm.component.installer.gds.rest.GDSRESTConnectorTest.GDSTestConnector.TestGDSRequester.TestURLConnectionFactory.TestURLConnection; -import org.graalvm.component.installer.MemoryFeedback.Case; -import org.graalvm.component.installer.remote.FileDownloader; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import static java.nio.charset.StandardCharsets.UTF_8; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * - * @author odouda - */ -public class GDSRESTConnectorTest extends TestBase { - static final String VERSION_STRING = "21.3.0"; - static final Version TEST_VERSION = Version.fromString(VERSION_STRING); - static final String TEST_EMAIL = "mock@email.ofc"; - static final String TEST_ID = "D35D04EC5DB2F1F6E0531614000A615C"; - static final String TEST_TOKEN = "RDhCMUFEMUYwMjM1OEQ0MkUwNTMyRDE0MDAwQTAyRjI6NGZjMTFiMzAxMDVkOTAzMDk1NjM4MWJmODY4NWFmODRiYTk2NjEwYQ"; - static final String TEST_TOKEN_OLD = "OldCMUFEMUYwMjM1OEQ0MkUwNTMyRDE0MDAwQTAyRjI6NGZjMTFiMzAxMDVkOTAzMDk1NjM4MWJmODY4NWFmODRiYTk2NjEOld"; - static final String TEST_TOKEN_RESPONSE = "{\n" + " \"token\": \"" + TEST_TOKEN + "\",\n" + " \"status\": \"UNVERIFIED\"\n" + "}"; - static final String TEST_JAVA = "11"; - static final String TEST_JDK = "jdk" + TEST_JAVA; - static final String TEST_TOKEN_REQUEST_ACCEPT = "{\"type\":\"" + GDSRequester.ACCEPT_LICENSE + "\",\"token\":\"" + TEST_TOKEN_OLD + "\",\"licenseId\":\"gdsreleases.json\"}"; - static final String TEST_TOKEN_REQUEST_GENERATE = "{\"type\":\"" + GDSRequester.GENERATE_CONFIG + "\",\"email\":\"" + TEST_EMAIL + "\",\"licenseId\":\"gdsreleases.json\"}"; - static final String TEST_GDS_AGENT = String.format("GVM/%s (arch:%s; os:%s; java:%s)", - TEST_VERSION.toString(), - SystemUtils.ARCH.sysName(), - SystemUtils.OS.sysName(), - SystemUtils.getJavaMajorVersion()); - static final String WRONG_RESPONSE = "wrong response"; - static final String TEST_TOKEN_REVOKE = "{\"type\":\"" + GDSRequester.REVOKE_TOKEN + "\",\"downloadToken\":\"" + TEST_TOKEN + "\"}"; - static final String TEST_TOKEN_REVOKE_ALL = "{\"type\":\"" + GDSRequester.REVOKE_TOKEN + "\",\"email\":\"" + TEST_EMAIL + "\"}"; - - final String testURL; - final GDSTestConnector testConnector; - final MemoryFeedback mf; - - @SuppressWarnings("this-escape") - public GDSRESTConnectorTest() throws IOException { - testURL = dataFile("data/gdsreleases.json").toUri().toURL().toString(); - testConnector = new GDSTestConnector(testURL, this, TEST_ID, TEST_VERSION); - delegateFeedback(mf = new MemoryFeedback()); - } - - @After - public void tearDown() { - assertTrue(mf.toString(), mf.isEmpty()); - } - - @Test - public void testConstructor() { - assertEquals(testURL, testConnector.baseURL); - assertEquals(TEST_ID, testConnector.productId); - assertEquals(TEST_GDS_AGENT, testConnector.gdsUserAgent); - GDSTestConnector conn = null; - try { - conn = new GDSTestConnector(null, this, TEST_ID, TEST_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector("", this, TEST_ID, TEST_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector("notURL", this, TEST_ID, TEST_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector(testURL, null, TEST_ID, TEST_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector(testURL, this, null, TEST_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector(testURL, this, "", TEST_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector(testURL, this, TEST_ID, null); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - try { - conn = new GDSTestConnector(testURL, this, TEST_ID, Version.NO_VERSION); - fail("IllegalArgumentException expected."); - } catch (IllegalArgumentException ex) { - // expected - } - - assertTrue(conn == null); - } - - @Test - public void testObtainArtifacts() { - testConnector.obtainArtifacts(); - checkBaseParams(GDSRESTConnector.ENDPOINT_ARTIFACTS); - - testConnector.obtainArtifacts(TEST_JAVA); - List metas = checkBaseParams(GDSRESTConnector.ENDPOINT_ARTIFACTS); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_JAVA + TEST_JDK)); - - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - } - - @Test - public void testObtainComponents() { - testConnector.obtainComponents(); - List metas = checkBaseParams(GDSRESTConnector.ENDPOINT_ARTIFACTS); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_TYPE_COMP)); - - testConnector.obtainComponents(VERSION_STRING); - metas = checkBaseParams(GDSRESTConnector.ENDPOINT_ARTIFACTS); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_TYPE_COMP)); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_RELEASE + VERSION_STRING)); - - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - } - - @Test - public void testObtainProduct() { - testConnector.obtainProduct(); - Map> params = testConnector.testParams; - testConnector.getParams(); - assertTrue(testConnector.testParams.isEmpty()); - assertEquals(GDSRESTConnector.QUERRY_PRODUCT_NAME, params.get(GDSRESTConnector.QUERRY_DISPLAY_NAME).get(0)); - assertEquals(GDSRESTConnector.QUERRY_LIMIT_VAL, params.get(GDSRESTConnector.QUERRY_LIMIT_KEY).get(0)); - assertEquals(GDSRESTConnector.ENDPOINT_PRODUCTS, testConnector.endpoint); - - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - } - - @Test - public void testObtainReleases() { - testConnector.obtainReleases(); - List metas = checkBaseParams(GDSRESTConnector.ENDPOINT_ARTIFACTS); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_TYPE_CORE)); - - testConnector.obtainReleases(TEST_JAVA); - metas = checkBaseParams(GDSRESTConnector.ENDPOINT_ARTIFACTS); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_TYPE_CORE)); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_JAVA + TEST_JDK)); - - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - mf.checkMem(Case.FRM, "OLDS_ReleaseFile"); - mf.checkMem(Case.MSG, "MSG_UsingFile", "OLDS_ReleaseFile", ""); - } - - @Test - public void testMakeArtifactsURL() { - String artURL = testConnector.makeArtifactsURL(TEST_JAVA); - assertTrue(artURL.equals(testURL + GDSRESTConnector.ENDPOINT_ARTIFACTS)); - Map> params = testConnector.testParams; - testConnector.getParams(); - assertTrue(testConnector.testParams.isEmpty()); - assertEquals(TEST_ID, params.get(GDSRESTConnector.QUERRY_PRODUCT).get(0)); - List metas = params.get(GDSRESTConnector.QUERRY_METADATA); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_OS + SystemUtils.OS.get().getName())); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_ARCH + SystemUtils.ARCH.get().getName())); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_JAVA + TEST_JDK)); - } - - @Test - public void testMakeReleaseCatalogURL() { - String artURL = testConnector.makeReleaseCatalogURL(VERSION_STRING, TEST_JAVA); - assertTrue(artURL.equals(testURL + GDSRESTConnector.ENDPOINT_ARTIFACTS)); - Map> params = testConnector.testParams; - testConnector.getParams(); - assertTrue(testConnector.testParams.isEmpty()); - assertEquals(TEST_ID, params.get(GDSRESTConnector.QUERRY_PRODUCT).get(0)); - List metas = params.get(GDSRESTConnector.QUERRY_METADATA); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_OS + SystemUtils.OS.get().getName())); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_ARCH + SystemUtils.ARCH.get().getName())); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_JAVA + TEST_JDK)); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_RELEASE + VERSION_STRING)); - } - - @Test - public void testMakeArtifactDownloadURL() { - String mockId = "mockArtifactId"; - URL artURL = testConnector.makeArtifactDownloadURL(mockId); - assertEquals(testURL + GDSRESTConnector.ENDPOINT_ARTIFACTS + mockId + GDSRESTConnector.ENDPOINT_DOWNLOAD, artURL.toString()); - } - - @Test - public void testFillBasics() throws MalformedURLException { - FileDownloader fd = new FileDownloader(TEST_ID, SystemUtils.toURL(testURL), this); - testConnector.fillBasics(fd); - Map header = fd.getRequestHeaders(); - assertEquals(GDSRESTConnector.HEADER_VAL_GZIP, header.get(GDSRESTConnector.HEADER_ENCODING)); - assertEquals(TEST_GDS_AGENT, header.get(GDSRESTConnector.HEADER_USER_AGENT)); - } - - @Test - public void testSendVerificationEmail() { - String tkn = testConnector.sendVerificationEmail(null, testURL, TEST_TOKEN_OLD); - assertEquals(TEST_TOKEN_OLD, tkn); - TestURLConnection tc = testConnector.conn; - assertEquals(TEST_TOKEN_REQUEST_ACCEPT, - tc.os.toString()); - assertTrue(tc.getDoOutput()); - Map> headers = tc.getRequestProperties(); - assertTrue(headers.size() == 2); - assertEquals(GDSRequester.HEADER_VAL_JSON, headers.get(GDSRequester.HEADER_CONTENT).get(0)); - assertEquals(TEST_GDS_AGENT, headers.get(GDSRESTConnector.HEADER_USER_AGENT).get(0)); - - testConnector.conn = null; - testConnector.is = new ByteArrayInputStream(TEST_TOKEN_RESPONSE.getBytes(UTF_8)); - - tkn = testConnector.sendVerificationEmail(TEST_EMAIL, testURL, null); - assertEquals(TEST_TOKEN, tkn); - tc = testConnector.conn; - assertEquals(TEST_TOKEN_REQUEST_GENERATE, - tc.os.toString()); - assertTrue(tc.getDoOutput()); - headers = tc.getRequestProperties(); - assertTrue(headers.size() == 2); - assertEquals(GDSRequester.HEADER_VAL_JSON, headers.get(GDSRequester.HEADER_CONTENT).get(0)); - assertEquals(TEST_GDS_AGENT, headers.get(GDSRESTConnector.HEADER_USER_AGENT).get(0)); - - testConnector.conn = null; - testConnector.is = new ByteArrayInputStream(WRONG_RESPONSE.getBytes(UTF_8)); - try { - testConnector.sendVerificationEmail(TEST_EMAIL, testURL, null); - fail("FailedOperationException expected."); - } catch (FailedOperationException ex) { - assertEquals("ERR_ResponseBody", ex.getMessage()); - // expected - } - tc = testConnector.conn; - assertEquals(TEST_TOKEN_REQUEST_GENERATE, - tc.os.toString()); - assertTrue(tc.getDoOutput()); - headers = tc.getRequestProperties(); - assertTrue(headers.size() == 2); - assertEquals(GDSRequester.HEADER_VAL_JSON, headers.get(GDSRequester.HEADER_CONTENT).get(0)); - assertEquals(TEST_GDS_AGENT, headers.get(GDSRESTConnector.HEADER_USER_AGENT).get(0)); - } - - @Test - public void testRevokeToken() { - testConnector.revokeToken(TEST_TOKEN); - TestURLConnection tc = testConnector.conn; - assertEquals(TEST_TOKEN_REVOKE, tc.os.toString()); - assertTrue(tc.getDoOutput()); - Map> headers = tc.getRequestProperties(); - assertTrue(headers.size() == 2); - assertEquals(GDSRequester.HEADER_VAL_JSON, headers.get(GDSRequester.HEADER_CONTENT).get(0)); - assertEquals(TEST_GDS_AGENT, headers.get(GDSRESTConnector.HEADER_USER_AGENT).get(0)); - } - - @Test - public void testRevokeTokens() { - testConnector.revokeTokens(TEST_EMAIL); - TestURLConnection tc = testConnector.conn; - assertEquals(TEST_TOKEN_REVOKE_ALL, tc.os.toString()); - assertTrue(tc.getDoOutput()); - Map> headers = tc.getRequestProperties(); - assertTrue(headers.size() == 2); - assertEquals(GDSRequester.HEADER_VAL_JSON, headers.get(GDSRequester.HEADER_CONTENT).get(0)); - assertEquals(TEST_GDS_AGENT, headers.get(GDSRESTConnector.HEADER_USER_AGENT).get(0)); - } - - private List checkBaseParams(String endpoint) { - Map> params = testConnector.testParams; - testConnector.getParams(); - assertTrue(testConnector.testParams.isEmpty()); - assertEquals(GDSRESTConnector.QUERRY_LIMIT_VAL, params.get(GDSRESTConnector.QUERRY_LIMIT_KEY).get(0)); - assertEquals(TEST_ID, params.get(GDSRESTConnector.QUERRY_PRODUCT).get(0)); - List metas = params.get(GDSRESTConnector.QUERRY_METADATA); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_OS + SystemUtils.OS.get().getName())); - assertTrue(metas.contains(GDSRESTConnector.QUERRY_ARCH + SystemUtils.ARCH.get().getName())); - assertEquals(endpoint, testConnector.endpoint); - return metas; - } - - static final class GDSTestConnector extends GDSRESTConnector { - String endpoint; - Map> testParams; - TestURLConnection conn = null; - ByteArrayInputStream is = new ByteArrayInputStream(TEST_TOKEN_RESPONSE.getBytes(UTF_8)); - - GDSTestConnector(String baseURL, Feedback feedback, String productId, Version gvmVersion) { - super(baseURL, feedback, productId, gvmVersion); - } - - @Override - public Map> getParams() { - // used to build URL querry then cleared - Map> parms = super.getParams(); - testParams = Map.copyOf(parms); - return Collections.emptyMap(); - } - - @Override - protected FileDownloader obtain(String endp) { - this.endpoint = endp; - // endpoint is appended to baseURL - return super.obtain(""); - } - - @Override - GDSRequester getGDSRequester(String acceptLicLink, String licID) throws MalformedURLException { - return new TestGDSRequester(SystemUtils.toURL(acceptLicLink), licID); - } - - final class TestGDSRequester extends GDSRESTConnector.GDSRequester { - TestURLConnectionFactory fac = new TestURLConnectionFactory(); - - TestGDSRequester(URL licenseUrl, String licID) { - super(licenseUrl, licID); - } - - @Override - URLConnectionFactory getConnectionFactory() throws MalformedURLException { - return fac; - } - - final class TestURLConnectionFactory implements URLConnectionFactory { - - @Override - public URLConnection createConnection(URL u, Configure configCallback) throws IOException { - if (conn == null) { - conn = new TestURLConnection(u); - configCallback.accept(conn); - } - return conn; - } - - final class TestURLConnection extends URLConnection { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - TestURLConnection(URL url) { - super(url); - } - - @Override - public void connect() throws IOException { - } - - @Override - public OutputStream getOutputStream() throws IOException { - return os; - } - - @Override - public InputStream getInputStream() throws IOException { - return is; - } - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSTokenStorageTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSTokenStorageTest.java deleted file mode 100644 index 79973846e7a7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/GDSTokenStorageTest.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommandTestBase; -import static org.graalvm.component.installer.CommonConstants.PATH_GDS_CONFIG; -import static org.graalvm.component.installer.CommonConstants.PATH_USER_GU; -import static org.graalvm.component.installer.CommonConstants.SYSPROP_USER_HOME; -import org.graalvm.component.installer.gds.GdsCommands; -import static org.graalvm.component.installer.gds.rest.GDSTokenStorage.GRAAL_EE_DOWNLOAD_TOKEN; -import static org.graalvm.component.installer.gds.rest.GDSTokenStorage.Source; -import org.graalvm.component.installer.MemoryFeedback.Case; -import org.graalvm.component.installer.MemoryFeedback; -import static org.graalvm.component.installer.gds.rest.TestGDSTokenStorage.testPath; -import org.junit.After; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Before; -import org.junit.Test; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Properties; - -/** - * - * @author odouda - */ -public class GDSTokenStorageTest extends CommandTestBase { - static final Path tstPath = Path.of(System.getProperty(SYSPROP_USER_HOME), PATH_USER_GU, PATH_GDS_CONFIG + "test"); - static final String MOCK_TOKEN_DEFAULT = "MOCK_TOKEN_DEFAULT"; - static final String MOCK_TOKEN_ENV = "MOCK_TOKEN_ENV"; - static final String MOCK_TOKEN_USER = "MOCK_TOKEN_USER"; - static final String MOCK_EMAIL = "some@mock.email"; - - MemoryFeedback mf; - TestGDSTokenStorage ts; - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - delegateFeedback(mf = new MemoryFeedback()); - reload(); - clean(); - } - - @After - public void tearDown() throws IOException { - clean(); - assertTrue(mf.toString(), mf.isEmpty()); - } - - private void reload() { - ts = new TestGDSTokenStorage(this, this); - } - - private static void clean() throws IOException { - Files.deleteIfExists(testPath); - Files.deleteIfExists(tstPath); - } - - @Test - public void testPropPath() { - Path pth = new GDSTokenStorage(this, this).getPropertiesPath(); - assertEquals(Path.of(System.getProperty(SYSPROP_USER_HOME), PATH_USER_GU, PATH_GDS_CONFIG), pth); - } - - @Test - public void testGetTokenSource() throws IOException { - assertEquals(Source.NON, ts.getConfSource()); - - assertTokenSource(null, Source.NON); - - store(testPath, "SOME_DIFFERENT_KEY", MOCK_TOKEN_DEFAULT); - assertTokenSource(null, Source.NON); - - store(testPath, GRAAL_EE_DOWNLOAD_TOKEN, MOCK_TOKEN_DEFAULT); - assertTokenSource(MOCK_TOKEN_DEFAULT, Source.FIL); - - envParameters.put(GRAAL_EE_DOWNLOAD_TOKEN, MOCK_TOKEN_ENV); - assertTokenSource(MOCK_TOKEN_ENV, Source.ENV); - - options.put(GdsCommands.OPTION_GDS_CONFIG, tstPath.toString()); - store(tstPath, GRAAL_EE_DOWNLOAD_TOKEN, MOCK_TOKEN_USER); - assertTokenSource(MOCK_TOKEN_USER, Source.CMD); - - store(tstPath, GRAAL_EE_DOWNLOAD_TOKEN, ""); - assertTokenSource(MOCK_TOKEN_ENV, Source.ENV); - - envParameters.put(GRAAL_EE_DOWNLOAD_TOKEN, ""); - assertTokenSource(MOCK_TOKEN_DEFAULT, Source.FIL); - - store(testPath, GRAAL_EE_DOWNLOAD_TOKEN, ""); - assertTokenSource(null, Source.NON); - - try (OutputStream os = Files.newOutputStream(ts.getPropertiesPath())) { - os.write("key1=foo\\u0123\nkey2=bar\\u0\\n".getBytes()); - os.flush(); - } - reload(); - ts.getToken(); - mf.checkMem(Case.ERR, "ERR_CouldNotLoadToken", ts.getPropertiesPath(), "Malformed \\uxxxx encoding."); - } - - @Test - public void testSetToken() { - assertEquals(null, ts.getToken()); - assertEquals(Source.NON, ts.getConfSource()); - - ts.setToken(MOCK_TOKEN_DEFAULT); - assertEquals(MOCK_TOKEN_DEFAULT, ts.getToken()); - assertEquals(Source.FIL, ts.getConfSource()); - - ts.setToken(""); - assertEquals(null, ts.getToken()); - assertEquals(Source.NON, ts.getConfSource()); - - try { - ts.setToken(null); - fail("Expected IllegalArgumentException."); - } catch (IllegalArgumentException ex) { - // expected - } - } - - @Test - public void testSave() throws IOException { - assertTokenSource(null, Source.NON); - ts.setToken(MOCK_TOKEN_DEFAULT); - assertTokenSource(null, Source.NON); - ts.setToken(MOCK_TOKEN_DEFAULT); - ts.save(); - assertTokenSource(MOCK_TOKEN_DEFAULT, Source.FIL); - } - - @Test - public void testPrintToken() throws IOException { - ts.printToken(); - store(testPath, GRAAL_EE_DOWNLOAD_TOKEN, MOCK_TOKEN_DEFAULT); - reload(); - ts.printToken(); - envParameters.put(GRAAL_EE_DOWNLOAD_TOKEN, MOCK_TOKEN_ENV); - ts.printToken(); - options.put(GdsCommands.OPTION_GDS_CONFIG, tstPath.toString()); - store(tstPath, GRAAL_EE_DOWNLOAD_TOKEN, MOCK_TOKEN_USER); - ts.printToken(); - mf.checkMem(Case.MSG, "MSG_EmptyToken", null, ""); - mf.checkMem(Case.FRM, "MSG_PrintTokenFile", testPath.toString()); - mf.checkMem(Case.MSG, "MSG_PrintToken", MOCK_TOKEN_DEFAULT, "MSG_PrintTokenFile"); - mf.checkMem(Case.FRM, "MSG_PrintTokenEnv", GRAAL_EE_DOWNLOAD_TOKEN); - mf.checkMem(Case.MSG, "MSG_PrintToken", MOCK_TOKEN_ENV, "MSG_PrintTokenEnv"); - mf.checkMem(Case.FRM, "MSG_PrintTokenCmdFile", tstPath.toString()); - mf.checkMem(Case.MSG, "MSG_PrintToken", MOCK_TOKEN_USER, "MSG_PrintTokenCmdFile"); - } - - @Test - public void testRevokeToken() { - ts.revokeToken(null); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoRevokableToken"); - - ts.revokeToken(""); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoRevokableToken"); - - ts.revokeToken(MOCK_TOKEN_DEFAULT); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "GDSRESTConnector.revokeToken:" + MOCK_TOKEN_DEFAULT); - mf.checkMem(Case.MSG, "MSG_AcceptRevoke"); - - ts.setToken(MOCK_TOKEN_DEFAULT); - assertEquals(MOCK_TOKEN_DEFAULT, ts.getToken()); - ts.revokeToken(null); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "GDSRESTConnector.revokeToken:" + MOCK_TOKEN_DEFAULT); - mf.checkMem(Case.MSG, "MSG_AcceptRevoke"); - - ts.makeConn = false; - - ts.revokeToken(null); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - - ts.revokeToken(""); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - - ts.revokeToken(MOCK_TOKEN_DEFAULT); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - - ts.setToken(MOCK_TOKEN_DEFAULT); - assertEquals(MOCK_TOKEN_DEFAULT, ts.getToken()); - ts.revokeToken(null); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - } - - @Test - public void testRevokeAllTokens() { - ts.revokeAllTokens(null); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoEmail"); - - ts.revokeAllTokens(""); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoEmail"); - - try { - ts.revokeAllTokens(MOCK_TOKEN_DEFAULT); - fail("Expected FailedOperationException."); - } catch (org.graalvm.component.installer.FailedOperationException ex) { - assertEquals("ERR_EmailNotValid", ex.getMessage()); - } - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - - ts.revokeAllTokens(MOCK_EMAIL); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "GDSRESTConnector.revokeTokens:" + MOCK_EMAIL); - mf.checkMem(Case.MSG, "MSG_AcceptRevoke"); - - ts.makeConn = false; - - ts.revokeAllTokens(null); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - - ts.revokeAllTokens(""); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - - ts.revokeAllTokens(MOCK_TOKEN_DEFAULT); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - - ts.revokeAllTokens(MOCK_EMAIL); - mf.checkMem(Case.MSG, "GDSTokenStorage.makeConnector"); - mf.checkMem(Case.MSG, "MSG_NoGDSAddress"); - } - - private void assertTokenSource(String tkn, Source src) { - reload(); - assertEquals(tkn, ts.getToken()); - assertEquals(src, ts.getConfSource()); - } - - private static void store(Path dest, String key, String val) throws IOException { - Properties props = new Properties(); - props.put(key, val); - try (OutputStream os = Files.newOutputStream(dest)) { - props.store(os, null); - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/TestGDSTokenStorage.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/TestGDSTokenStorage.java deleted file mode 100644 index e394bbe34226..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/TestGDSTokenStorage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommandInput; -import static org.graalvm.component.installer.CommonConstants.PATH_GDS_CONFIG; -import static org.graalvm.component.installer.CommonConstants.PATH_USER_GU; -import static org.graalvm.component.installer.CommonConstants.SYSPROP_USER_HOME; -import org.graalvm.component.installer.Feedback; -import java.nio.file.Path; -import org.graalvm.component.installer.Version; - -/** - * - * @author odouda - */ -class TestGDSTokenStorage extends GDSTokenStorage { - static Path testPath = Path.of(System.getProperty(SYSPROP_USER_HOME), PATH_USER_GU, "test" + PATH_GDS_CONFIG); - private Feedback fb; - - TestGDSTokenStorage(Feedback feedback, CommandInput input) { - super(feedback, input); - fb = feedback.withBundle(GDSChannel.class); - } - - @Override - public Path getPropertiesPath() { - return testPath; - } - - public boolean makeConn = true; - - @Override - protected GDSRESTConnector makeConnector() { - fb.verbatimOut("GDSTokenStorage.makeConnector", false); - return makeConn ? new GDSRESTConnector("http://mock.url", fb, PATH_USER_GU, Version.fromString("1.0.0")) { - @Override - public void revokeToken(String token) { - fb.verbatimOut("GDSRESTConnector.revokeToken:" + token, false); - } - - @Override - public void revokeTokens(String mail) { - fb.verbatimOut("GDSRESTConnector.revokeTokens:" + mail, false); - } - } : null; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/data/gdsreleases.json b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/data/gdsreleases.json deleted file mode 100644 index 8710707794ef..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/gds/rest/data/gdsreleases.json +++ /dev/null @@ -1,9676 +0,0 @@ -{ - "items": [ - { - "id": "DC0D45769EBF406EE0538714000A4386", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - } - ], - "displayName": "Java on Truffle LLVM Java libraries macos amd64 22.1.0 jdk17 ee", - "checksum": "3f86f93cc44998b86aa6a9a5e59b31f0a35e8b5692cca42b6b04b485636c6b5c", - "status": "PUBLISHED", - "timeCreated": "2022-04-07T13:08:39.568Z" - }, - { - "id": "DC04E2FBFA88CE4EE0538714000A1AA0", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - } - ], - "displayName": "Java on Truffle LLVM Java libraries macos amd64 22.1.0 jdk11 ee", - "checksum": "8cb10b44752cbea9a4f37aea66d6a9f273b265fb6c0d718ed6d7058ab1f0965e", - "status": "PUBLISHED", - "timeCreated": "2022-04-07T13:08:30.900Z" - }, - { - "id": "DC0D45769E5D406EE0538714000A4386", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - } - ], - "displayName": "Java on Truffle LLVM Java libraries macos amd64 22.2.0 jdk17 ee", - "checksum": "a5b4a77200007fb1d52344981e0c803d394aae8c6029ecf279ddff0a2a45f34a", - "status": "PUBLISHED", - "timeCreated": "2022-04-07T12:49:42.520Z" - }, - { - "id": "DC02FD0B9C72B342E0538714000ACF2A", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - } - ], - "displayName": "Java on Truffle LLVM Java libraries macos amd64 22.2.0 jdk11 ee", - "checksum": "71b26f91df8727a548aba9394943ee3221bc2a9062d7f44e252dae8cc65480a3", - "status": "PUBLISHED", - "timeCreated": "2022-04-07T12:49:31.738Z" - }, - { - "id": "DBD255350DBD2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm windows amd64 22.2.0 jdk17 ee", - "checksum": "6560d7d558cfe40143f57648e2768fbd29ce1ec6a24d6b10cf6f08d2040215f0", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:46:07.030Z" - }, - { - "id": "DBD255350DAF2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle windows amd64 22.2.0 jdk17 ee", - "checksum": "94be13b56e82187e3c7f51a3ddc78d7c553d3e101318dfc6f47bc0725a4bf9f7", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:46:05.735Z" - }, - { - "id": "DBD255350DA02F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs windows amd64 22.2.0 jdk17 ee", - "checksum": "9ac3c76459c7915de387d06d278ef5713b013dda5d4218e9f37d88607561d9b6", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:46:04.443Z" - }, - { - "id": "DBD255350D932F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image windows amd64 22.2.0 jdk17 ee", - "checksum": "aacc592d961c2d1d078d93e0a0decfe2fbf4e4e503f03ee11a1caba7f784e403", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:46:03.144Z" - }, - { - "id": "DBD255350D8A2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core windows amd64 22.2.0 jdk17 ee", - "checksum": "bd45903f9b58b28d9ff53346655eb39f6be6050b2133edfcf6ca1b9f05282128", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:46:01.858Z" - }, - { - "id": "DBD255350D822F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk17 windows amd64", - "checksum": "12ad12141f08712c200c8352b884b8f1eeb8b3c0dfee3b87c76ed05355ab701d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:46:00.605Z" - }, - { - "id": "DBD255350D752F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain macos amd64 22.2.0 jdk17 ee", - "checksum": "e3239f0d39924f8f53e6a35e3901a8ed64f9b83eeda15ebb75f5f1b15f438320", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:59.416Z" - }, - { - "id": "DBD255350D672F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm macos amd64 22.2.0 jdk17 ee", - "checksum": "1fb9daf6fb2bff476bed9bdafad7a655bbe2ed864096c0cadc935416c6e3964a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:58.115Z" - }, - { - "id": "DBD255350D582F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python macos amd64 22.2.0 jdk17 ee", - "checksum": "424b5e6c5bfb8c6d4d87ed9147d06ee5498f1944d4d4f492bd8cdc23e3690faf", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:56.782Z" - }, - { - "id": "DBD255350D492F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby macos amd64 22.2.0 jdk17 ee", - "checksum": "d5e44c0c6238daa5e695b94f678a9a4427df5ca40e5ffcda698c5150214da8dc", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:55.484Z" - }, - { - "id": "DBD25450B9703307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle macos amd64 22.2.0 jdk17 ee", - "checksum": "e849dcd29d74aa0235aadda72ea4a23c6c85d9dbdcfd3dd69fe99f8acb07cbf1", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:54.054Z" - }, - { - "id": "DBD255350D3A2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs macos amd64 22.2.0 jdk17 ee", - "checksum": "295ea335c67036302a03d6a1f33d90320c7ac4ad133752c4f67039ec3cdf61e0", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:52.801Z" - }, - { - "id": "DBD255350D2D2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image macos amd64 22.2.0 jdk17 ee", - "checksum": "dc8e5f940260fb0a5fdacd68ab9136cafcf69806420e6112f94b40f14ff2b919", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:51.388Z" - }, - { - "id": "DBD25450B9673307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core macos amd64 22.2.0 jdk17 ee", - "checksum": "26dd2f88d8bffa535756a74ae76c6c8d18f9de0d4511eaf870a3cf27f4defa27", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:50.172Z" - }, - { - "id": "DBD25450B95F3307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk17 darwin amd64", - "checksum": "4730d1ef0a7126a15c1a388ffd99c0e1ff2783676bc4996acb657a7fff6a0139", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:49.020Z" - }, - { - "id": "DBD255350D202F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux aarch64 22.2.0 jdk17 ee", - "checksum": "66e9a79380202c2fc954e83f1856b69c8edde3909e5191708166f849c3037fda", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:47.696Z" - }, - { - "id": "DBD206227B6A3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux aarch64 22.2.0 jdk17 ee", - "checksum": "251076be28a1419773fe7c1050f399acf626d4a9918ec212fbc82bba6b080b3b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:46.280Z" - }, - { - "id": "DBD206227B5B3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux aarch64 22.2.0 jdk17 ee", - "checksum": "57554962809ba66cd8e63613194a63ead817f24afc12c8dcced7feb0c2b74ae8", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:44.880Z" - }, - { - "id": "DBD255350D122F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux aarch64 22.2.0 jdk17 ee", - "checksum": "4674692f9469edcfa83fe230d3c7d942ba26557a403efcd431ad5da7d1358eb5", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:43.593Z" - }, - { - "id": "DBD206227B4D3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm windows amd64 22.2.0 jdk11 ee", - "checksum": "307bdc705411bc07a834b175acf3a6ea048a12d0d31b8635004f1a6a9124ef3c", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:43.331Z" - }, - { - "id": "DBD206227B3E3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux aarch64 22.2.0 jdk17 ee", - "checksum": "e896ed6ad4e9588e0a8c9e4b10d3138eb98116d9d1f0517aaeca273c71641e56", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:42.309Z" - }, - { - "id": "DBD255350D042F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle windows amd64 22.2.0 jdk11 ee", - "checksum": "b4c02b54a1c8a8ee03b129e180104e6997cc6522e501c1adfe2c2d7ff246bf3d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:42.036Z" - }, - { - "id": "DBD255350CF72F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux aarch64 22.2.0 jdk17 ee", - "checksum": "f77427d240c48b1dc8d0b02d7212016c73518f359a2706486a2f803804ed6579", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:41.074Z" - }, - { - "id": "DBD206227B2F3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs windows amd64 22.2.0 jdk11 ee", - "checksum": "a1bfd2bb5343d0e12e0d025804e54d0801977a335b792fdb33e58eaab71197b8", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:40.768Z" - }, - { - "id": "DBD206227B263259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux aarch64 22.2.0 jdk17 ee", - "checksum": "0528b454f95bbd7aac53f9982faa1a48e2a64286378a7075c6bd0f21246eb20b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:39.781Z" - }, - { - "id": "DBD255350CEA2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image windows amd64 22.2.0 jdk11 ee", - "checksum": "1a699587304dc71ad40fc8cb8f5587bb50e385b9ba15c64fa299bc1b41c0ca8f", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:39.477Z" - }, - { - "id": "DBD206227B1E3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk17 linux aarch64", - "checksum": "f015e8cbbf97d6535fa76657335f766e60f2aa5395275b7e2edc31b75f69d762", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:38.630Z" - }, - { - "id": "DBD255350CE12F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core windows amd64 22.2.0 jdk11 ee", - "checksum": "5bffeac3f90da3c781113045cb2b793fc5a631652e42a3da7c03ff2ffcace287", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:38.153Z" - }, - { - "id": "DBD206227B113259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux amd64 22.2.0 jdk17 ee", - "checksum": "afc469b00c91847be85f240cddc7af8f2baddcae2799a7213b34acb2a8f4836b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:37.495Z" - }, - { - "id": "DBD206227B093259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk11 windows amd64", - "checksum": "f843cb1068fcfab011182f1b3adf5a0e510fd6dd89ee4ee43d4747dedfa15534", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:37.035Z" - }, - { - "id": "DBD206227AFA3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle LLVM Java libraries linux amd64 22.2.0 jdk17 ee", - "checksum": "ae39bc58ffeb4b63312d27dc8a79e17575424470fe3ce8216690dda9b4e4bbd6", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:36.207Z" - }, - { - "id": "DBD255350CD42F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain macos amd64 22.2.0 jdk11 ee", - "checksum": "37c54e93d56eb961e05d1ddce99254627fde02e610bcc9a097f100c505c56e02", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:35.889Z" - }, - { - "id": "DBD25450B9513307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux amd64 22.2.0 jdk17 ee", - "checksum": "4d545378b7b7c121d09f08c09320c6d5a493e92729d50ed3ff0893da1a209384", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:34.928Z" - }, - { - "id": "DBD255350CC62F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm macos amd64 22.2.0 jdk11 ee", - "checksum": "f6b338fe0fbca0967be0b34960a92a7fd860a2dd7fc723eabb418260c7b55d4a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:34.474Z" - }, - { - "id": "DBD255350CB72F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python linux amd64 22.2.0 jdk17 ee", - "checksum": "3ddd45cd1ecb2df95bef345a2f22f86744610b21b80b5792f376ba8aa38f71af", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:33.506Z" - }, - { - "id": "DBD206227AEB3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python macos amd64 22.2.0 jdk11 ee", - "checksum": "069a4089318aacff56dff46d76d9b098586b30f5c02aa73a44cbd8976f770d6b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:33.175Z" - }, - { - "id": "DBD255350CA82F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux amd64 22.2.0 jdk17 ee", - "checksum": "c7eb2dee3692a8bf7f8590c96c99f0d3bdd3af17ad02647eb13b94e2fe3f2181", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:32.205Z" - }, - { - "id": "DBD25450B9423307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby macos amd64 22.2.0 jdk11 ee", - "checksum": "be38fff57316b909ef0695510a19671a6db1ac83a5c55a52c1da02b5a6a1d0f5", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:31.822Z" - }, - { - "id": "DBD206227ADC3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux amd64 22.2.0 jdk17 ee", - "checksum": "d7869b7bba6dac2c60f76e58cd9a6b5eadabfc6a18552a99b60f22b6bb13b74c", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:30.549Z" - }, - { - "id": "DBD255350C9A2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle macos amd64 22.2.0 jdk11 ee", - "checksum": "b30ce36cd913e2d36c3f3254199249dd26e2051d6aea0891cd1ec9d9e0ce8646", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:30.492Z" - }, - { - "id": "DBD25450B9333307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux amd64 22.2.0 jdk17 ee", - "checksum": "5e1cef1f3689371c9e39c30ce335cde999534a860a7743c5768e61f80bb395b6", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:29.265Z" - }, - { - "id": "DBD25450B9243307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs macos amd64 22.2.0 jdk11 ee", - "checksum": "4afdb1da810776d3514b7e190be5234a5081257cdd5797bb49fd9f41e3600107", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:28.967Z" - }, - { - "id": "DBD25450B9173307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux amd64 22.2.0 jdk17 ee", - "checksum": "88c56f763d686a71bba3806de04829650c0fc370f013e3b4f5df589541c0cbed", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:27.700Z" - }, - { - "id": "DBD255350C8D2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image macos amd64 22.2.0 jdk11 ee", - "checksum": "f8230f8bfb51cf9f9671b4f78db8ace31fbe74d53cbfc702d5931de24d22f3d5", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:27.679Z" - }, - { - "id": "DBD255350C842F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core macos amd64 22.2.0 jdk11 ee", - "checksum": "bcf84250ef8154e49d4b41ff60cc289c7c3980bd783737ae2c4a7578b049db51", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:26.474Z" - }, - { - "id": "DBD206227AD33259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux amd64 22.2.0 jdk17 ee", - "checksum": "2d8d5c8215db45528da319fafe34c6369fcffc0ef8b0d3e6891b4e3ea4c22e7b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:26.435Z" - }, - { - "id": "DBD206227ACB3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk11 darwin amd64", - "checksum": "29198b90900629cbb2587a13b37258eb6ca9f93ec18b1cf42f3f37683e797749", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:25.218Z" - }, - { - "id": "DBD206227AC33259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk17 linux amd64", - "checksum": "e7da04e927ecb28bf345702c5fe98aade1901c6f742d3f6ff1b157b82accc94c", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:24.919Z" - }, - { - "id": "DBD206227AB63259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux aarch64 22.2.0 jdk11 ee", - "checksum": "b7c808d1dc1f2e6d4d26b8fa9fa488e3c34f5422a5f350f4fb6eb6cc162124ac", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:23.962Z" - }, - { - "id": "DBD25450B9093307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux aarch64 22.2.0 jdk11 ee", - "checksum": "8d45638561e1486dad0a28c4f3f2ab175d6e3483bfde1cb3c4f7da6a505f3cc9", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:22.676Z" - }, - { - "id": "DBD206227AA73259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux aarch64 22.2.0 jdk11 ee", - "checksum": "7450b2106e745ee07b623d5577929174d72e065f1986ac51cabb5eba3d087af2", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:21.394Z" - }, - { - "id": "DBD206227A993259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux aarch64 22.2.0 jdk11 ee", - "checksum": "f0706d2695c1bc5ca13d7d470b98d37edda8ed8db56917f829116bff1dd19f86", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:20.131Z" - }, - { - "id": "DBD206227A8A3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux aarch64 22.2.0 jdk11 ee", - "checksum": "bdaf1a2b19d1eaf669355944c02250e44a2b85396fe1555a28c2560e48ea0ab3", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:18.808Z" - }, - { - "id": "DBD206227A7D3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux aarch64 22.2.0 jdk11 ee", - "checksum": "f37b23cbc162650b7047dff60d28acebdeb4f7968253c892cc38a9122b14acf4", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:17.553Z" - }, - { - "id": "DBD206227A743259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux aarch64 22.2.0 jdk11 ee", - "checksum": "0e00306b0b906c9e36d27f7ff5fc7bfa18d9cd0ff50de1017b26ab79da6b4288", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:16.183Z" - }, - { - "id": "DBD206227A6C3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk11 linux aarch64", - "checksum": "785c4d637f350abc4499ff5fe64a0f259234efd6c44c202ce291956a0135be81", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:15.065Z" - }, - { - "id": "DBD206227A5F3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux amd64 22.2.0 jdk11 ee", - "checksum": "2afcc41b5241170dacaf1d3817eb9c01232303479dcdcf289e60f3a96e489921", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:13.869Z" - }, - { - "id": "DBD206227A503259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle LLVM Java libraries linux amd64 22.2.0 jdk11 ee", - "checksum": "1d88d354def0132ebb7eb7b4af7c5fd39a3e2d9c6f039d8a8049ed5b6f28cfc4", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:12.481Z" - }, - { - "id": "DBD206227A423259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux amd64 22.2.0 jdk11 ee", - "checksum": "fb35b451af72c1cd66f1221c6596120e6780c0295a61ff900254caed9307d60c", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:11.081Z" - }, - { - "id": "DBD206227A333259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python linux amd64 22.2.0 jdk11 ee", - "checksum": "1fdd8a83aa176059d99a7656342309b44a11309f0455ba6d4851449911d7a6bd", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:09.799Z" - }, - { - "id": "DBD255350C752F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux amd64 22.2.0 jdk11 ee", - "checksum": "ec15f8e6a2f634cebdb9292fa49f445776521ce9038e1ba221e304f8f809c5c8", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:08.374Z" - }, - { - "id": "DBD25450B8FA3307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux amd64 22.2.0 jdk11 ee", - "checksum": "cadc60d80a054114759e8c5bc3071c0fef5f5453b501635593405e7904288c8c", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:07.075Z" - }, - { - "id": "DBD25450B8EB3307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux amd64 22.2.0 jdk11 ee", - "checksum": "60f2470a8acc676b03a1c2fe1cbea4bbac8f13e75aa0a53e53e8c61743e42a5f", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:05.535Z" - }, - { - "id": "DBD255350C682F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.2.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux amd64 22.2.0 jdk11 ee", - "checksum": "f01b37fd2b4260711e6261b09fedbe1bff455294f9fe77621298bf5c2b8ee91e", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:03.858Z" - }, - { - "id": "DBD255350C5F2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux amd64 22.2.0 jdk11 ee", - "checksum": "2a55e7d9e8da68eda0bdd0bb125cf8aec1ac4aa5b85d92c30852acc309aaf34d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:02.440Z" - }, - { - "id": "DBD206227A2B3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.2.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.2.0 on jdk11 linux amd64", - "checksum": "6a907488a6774982b63b48fd3c0ae1918fb163c6d232fc91a9a1731f34195f32", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:45:00.849Z" - }, - { - "id": "DBD255350C512F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm windows amd64 22.1.0 jdk17 ee", - "checksum": "620f5bc3ebb7b0855902147c69590e4a1f5c2311c0530bb66eb3d282cc6f2878", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:44.653Z" - }, - { - "id": "DBD25450B8DD3307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle windows amd64 22.1.0 jdk17 ee", - "checksum": "f5042b8ac43297d5fad5126d7f69f6a397548c0ea3ac1da1843417fa8067fa02", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:43.178Z" - }, - { - "id": "DBD255350C422F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs windows amd64 22.1.0 jdk17 ee", - "checksum": "33b262664d364d8c08c131d51d3054d211fc62c8348bf104034cf6f64088b0b3", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:41.913Z" - }, - { - "id": "DBD255350C352F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image windows amd64 22.1.0 jdk17 ee", - "checksum": "ac4c0080cc4a6e17e9531f1db61a31953c287f73c388ed205fd84f702962f53a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:40.568Z" - }, - { - "id": "DBD255350C2C2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=windows)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core windows amd64 22.1.0 jdk17 ee", - "checksum": "f4a1da20867e7727a3c79f5937c2b655ab07218de07a6beac2239687b130db73", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:39.242Z" - }, - { - "id": "DBD206227A223259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk17 windows amd64", - "checksum": "637dd02a6d7e5e5a635157eb1c364f0eafe9a32a92a913aef831a602a7188327", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:38.071Z" - }, - { - "id": "DBD255350C1F2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain macos amd64 22.1.0 jdk17 ee", - "checksum": "8966eda0f2cff318c4a9dea6749bb8ca98b02a84f1de3f7cb252c3a5d9aacac0", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:36.892Z" - }, - { - "id": "DBD255350C112F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm windows amd64 22.1.0 jdk11 ee", - "checksum": "2e89ea20945dd5115f66655b193da708bf142e3991cc9fccdc588a79e1aa2423", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:36.484Z" - }, - { - "id": "DBD255350C032F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm macos amd64 22.1.0 jdk17 ee", - "checksum": "69725444da99014ae04ea7a42825cca5feff793c01fb26dce60511ccc925920d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:35.532Z" - }, - { - "id": "DBD206227A143259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle windows amd64 22.1.0 jdk11 ee", - "checksum": "a57051bcb74078c4d6ba6acbe3fa0a328d2e7ccea40b6a5d14692c88593a1a65", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:35.136Z" - }, - { - "id": "DBD206227A053259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python macos amd64 22.1.0 jdk17 ee", - "checksum": "128e0a678d0574dafb95e6718c0604e419d89c5169d5e7fda3367050d9257067", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:34.202Z" - }, - { - "id": "DBD255350BF42F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages\\nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs windows amd64 22.1.0 jdk11 ee", - "checksum": "466df4c0ee0bec23412be6f502921149cc0cb7ecccac2838d9e60ffd29eed59d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:33.807Z" - }, - { - "id": "DBD255350BE52F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby macos amd64 22.1.0 jdk17 ee", - "checksum": "6ce7af7a23fb4c81ffb394718f75eb22c942242280db5e87e4afd63a5c11cf39", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:32.736Z" - }, - { - "id": "DBD255350BD82F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image windows amd64 22.1.0 jdk11 ee", - "checksum": "9413f9568c3266926d5db38e17928b134f110f084530cae191cbd32724340c8a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:31.960Z" - }, - { - "id": "DBD2062279F73259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - } - ], - "displayName": "Java on Truffle macos amd64 22.1.0 jdk17 ee", - "checksum": "53fe8597cc413ef2aeb399a8f72d452f9f4014fdc76a641d19f911ca3368591b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:31.368Z" - }, - { - "id": "DBD255350BCF2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=windows)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core windows amd64 22.1.0 jdk11 ee", - "checksum": "920d0d48ec3d72e61f88b240c3b802f9cd721f2214be8e5b3f6d8ea62034c2b2", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:30.564Z" - }, - { - "id": "DBD255350BC02F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs macos amd64 22.1.0 jdk17 ee", - "checksum": "d342707334c6b32763bef5f13f941992ddd8a1f5dce7ddc3f80b0a02e45f0a69", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:30.038Z" - }, - { - "id": "DBD255350BB82F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "windows", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk11 windows amd64", - "checksum": "962fd2ddf7de419c60768720cdfc2cf030f961a497b5d25dba801f1101c454a3", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:29.244Z" - }, - { - "id": "DBD25450B8D03307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image macos amd64 22.1.0 jdk17 ee", - "checksum": "6cbe622afd6438cf193fce5e2395a1493bf59cfd9821176dd85e1a0f8e48c430", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:28.695Z" - }, - { - "id": "DBD255350BAB2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain macos amd64 22.1.0 jdk11 ee", - "checksum": "7aee6d0fec0d1bc3a01ae82a1401bedf6d75aceb7405a044f60b71271ec78c44", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:28.031Z" - }, - { - "id": "DBD255350BA22F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=macos)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core macos amd64 22.1.0 jdk17 ee", - "checksum": "a38dea30d61647ae0f51a841408884cf97d4ec4f7e5ae6bc2d039deff3c441f6", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:27.348Z" - }, - { - "id": "DBD255350B942F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm macos amd64 22.1.0 jdk11 ee", - "checksum": "aad31a5483add56a5f0c7375c1123d66ff85c1b589858c97f3d15c6382b9ad8d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:25.291Z" - }, - { - "id": "DBD255350B8C2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk17 darwin amd64", - "checksum": "28d80a7a959ec9a1198af8740b86dde19aa9fc9223492cfe82fd5df0cac6eeee", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:24.781Z" - }, - { - "id": "DBD255350B7D2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python macos amd64 22.1.0 jdk11 ee", - "checksum": "75f11dae4d2d1c4567beace4b7ebe4e4869b0b07d8e9b3e18d1262ed6d596540", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:23.901Z" - }, - { - "id": "DBD2062279EA3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux aarch64 22.1.0 jdk17 ee", - "checksum": "27bf57e667f67e4d8d80fac62cecc3ecba5da1846af2326d3985633f59268d1b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:23.600Z" - }, - { - "id": "DBD2062279DB3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby macos amd64 22.1.0 jdk11 ee", - "checksum": "ed278b0c7d39ef2aeb9d89d0aed3a0ecd2259773b7a0ddb8ab7b99587cd2d1bd", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:22.564Z" - }, - { - "id": "DBD255350B6F2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux aarch64 22.1.0 jdk17 ee", - "checksum": "2eda17d89b9e8852d61e5e54b78e5f1f1110377380cab317794b2aee0ebb5bb2", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:22.284Z" - }, - { - "id": "DBD255350B612F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle macos amd64 22.1.0 jdk11 ee", - "checksum": "e0151801b99bd08ec4ff4cc2c61293334a820eccd5ba3f0d432322e472cee744", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:21.252Z" - }, - { - "id": "DBD2062279CC3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux aarch64 22.1.0 jdk17 ee", - "checksum": "f32ee527b511c23beba291f1afd790204bbcb2bca9f107142d4636a797386ffe", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:20.880Z" - }, - { - "id": "DBD255350B522F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs macos amd64 22.1.0 jdk11 ee", - "checksum": "34ffca39b884e53376b0d655dfe600a508472c7ef4330eb6ceb0a165713e7927", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:19.876Z" - }, - { - "id": "DBD2062279BF3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image macos amd64 22.1.0 jdk11 ee", - "checksum": "70cfc17667e66e7d36e5330392ae715b7c4b54d8ded82ca1f4103db2b3f957af", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:18.552Z" - }, - { - "id": "DBD255350B442F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux aarch64 22.1.0 jdk17 ee", - "checksum": "9cee1c0461aaa74b8058bf8c18ff59b0e6f650a4ba475e57c625ae333d198345", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:18.177Z" - }, - { - "id": "DBD25450B8C73307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=macos)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core macos amd64 22.1.0 jdk11 ee", - "checksum": "002277df75c5aac2e35c839ac7a908bc3bd9cc70ace72c87b5394b00e355496a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:17.249Z" - }, - { - "id": "DBD255350B352F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux aarch64 22.1.0 jdk17 ee", - "checksum": "30911a67944f6ee48f9155a31ba464a7d43aaab8fd04efc688a4a6b84c25adbc", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:16.829Z" - }, - { - "id": "DBD255350B2D2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "macos", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk11 darwin amd64", - "checksum": "7a6aaf36a99a355be3e28858ecb5209cc24edfdcb9051f8fc02a4e4d6d3561e4", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:16.081Z" - }, - { - "id": "DBD25450B8BA3307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux aarch64 22.1.0 jdk17 ee", - "checksum": "ec276e69c4d6ba2da77274fd4638a7d2773a450588eccbc4308c3116424eddaf", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:15.494Z" - }, - { - "id": "DBD255350B202F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux aarch64 22.1.0 jdk11 ee", - "checksum": "36877fa349d950612b79eed390251d43b7200e146506b94abaaec8082c661452", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:14.810Z" - }, - { - "id": "DBD255350B172F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=aarch64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux aarch64 22.1.0 jdk17 ee", - "checksum": "b2db29548578f16f8f19f785938f25ae7f55e94e42a13ea675bf55bd6580aef7", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:14.154Z" - }, - { - "id": "DBD255350B092F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux aarch64 22.1.0 jdk11 ee", - "checksum": "3f362edfe6e1710209aef881776ae3aee84e16f32fb24178473c2fe9e1b10228", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:13.438Z" - }, - { - "id": "DBD25450B8B23307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk17 linux aarch64", - "checksum": "bf3c8d6ac4c14ce6160c9a9e794c60ed0729e8a15b3c0026197590d4ef4191e3", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:12.974Z" - }, - { - "id": "DBD255350AFA2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux aarch64 22.1.0 jdk11 ee", - "checksum": "20a5517d3f56af05e2103bb9b3cfaa7413661f25c37ed1bf423d864847775910", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:12.074Z" - }, - { - "id": "DBD2062279B23259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux amd64 22.1.0 jdk17 ee", - "checksum": "e988094026d5e2ce09d9048aa48d44227089af6e8748cd5fddf08a0643c7594d", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:11.761Z" - }, - { - "id": "DBD2062279A43259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux aarch64 22.1.0 jdk11 ee", - "checksum": "ff120156ffbf33b320344bd45c6f84a68bb19b880dc9c55036ef3611f86eae62", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:10.719Z" - }, - { - "id": "DBD255350AEB2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle LLVM Java libraries linux amd64 22.1.0 jdk17 ee", - "checksum": "4a165d5d219b496c30cee94ff4dd8061a819b0d6721f1ecb7681300f5e24b52a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:10.433Z" - }, - { - "id": "DBD255350ADC2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux aarch64 22.1.0 jdk11 ee", - "checksum": "df87005d85671e64c91b60aa3e7217ab985174e8dc03d29026ee55d613c818b8", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:09.443Z" - }, - { - "id": "DBD2062279963259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux amd64 22.1.0 jdk17 ee", - "checksum": "61c0d5b4f882aaf0a6e25a33604fe126354f113000a0e52381ee231b4ba6a48f", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:09.075Z" - }, - { - "id": "DBD2062279893259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux aarch64 22.1.0 jdk11 ee", - "checksum": "083fe760cbf4b36ab80261baa3aa419817775c152eb5ada61fc37d27bd7e28f7", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:08.094Z" - }, - { - "id": "DBD255350ACD2F20E0538714000A44FF", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python linux amd64 22.1.0 jdk17 ee", - "checksum": "7c861c8565ccdcb2a5d663c19985c1939da29fec3a5397ed62dffbe86e982115", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:07.740Z" - }, - { - "id": "DBD25434029A402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=aarch64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux aarch64 22.1.0 jdk11 ee", - "checksum": "44cb18a5a14b37ec7e71679d9d50ef82bc26dda0d3ab86affc461b8e6f3e59b5", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:06.559Z" - }, - { - "id": "DBD20622797A3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux amd64 22.1.0 jdk17 ee", - "checksum": "78597ee67f801067c5f90d21cbcf420a60281179d82bde51073bdc4279ffe65a", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:06.351Z" - }, - { - "id": "DBD254340292402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "aarch64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk11 linux aarch64", - "checksum": "fb8c78bf85595f4d7db7cdbe22faae01f719114f355b32370e4bbbbab332fb57", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:05.281Z" - }, - { - "id": "DBD254340283402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - }, - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - } - ], - "displayName": "Java on Truffle linux amd64 22.1.0 jdk17 ee", - "checksum": "c62f45a087d3430f0721da63a39bc02f205d19da35c1e149a06c2f90ac61cf15", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:05.006Z" - }, - { - "id": "DBD254340276402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.llvm-toolchain", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "LLVM.org toolchain linux amd64 22.1.0 jdk11 ee", - "checksum": "efd9a31738930834e18f5699d820302c5fae7ff43450a80a667167f275e80a65", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:04.067Z" - }, - { - "id": "DBD20622796B3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux amd64 22.1.0 jdk17 ee", - "checksum": "2af640c3e885fb850aabb62d51417b28e22adb3a35c982319f7eb9c89c5fcf4b", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:03.672Z" - }, - { - "id": "DBD20622795C3259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso-llvm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle LLVM Java libraries linux amd64 22.1.0 jdk11 ee", - "checksum": "54297c2b5a3d241b1a2c265fc59ebb227b1c94fc473359c254df1aae474b47b9", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:02.745Z" - }, - { - "id": "DBD254340269402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Native Image linux amd64 22.1.0 jdk17 ee", - "checksum": "459788ea23daa4222fb2cb5bf35daa1e1fc22ea3e59d4a29f81dca5df501e393", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:02.310Z" - }, - { - "id": "DBD25434025B402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.wasm", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/wasm", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "GraalWasm linux amd64 22.1.0 jdk11 ee", - "checksum": "980710df75bf8bb781be42f8798afb079950d06b84c4a085558eae319c2677e7", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:01.429Z" - }, - { - "id": "DBD254340252402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=amd64)(java_version=17))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Core linux amd64 22.1.0 jdk17 ee", - "checksum": "8913f7de3183b77f42990c37fa76c5ff559bdaa5cdc3d3fdd09b6c28e45104c3", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:10:00.861Z" - }, - { - "id": "DBD254340243402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.python", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/python", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.Python linux amd64 22.1.0 jdk11 ee", - "checksum": "c38036fa962e5b0f363fd30be0cdc9c285da9a8f67ef0da06c146d57fe7654a4", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:59.945Z" - }, - { - "id": "DBD2062279543259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "java", - "value": "jdk17", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk17 linux amd64", - "checksum": "39493412ff6c8936c9c40be8d421b8432972e12b1cddb6b88eed70e7425bb317", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:59.775Z" - }, - { - "id": "DBD2062279453259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.llvm-toolchain", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.ruby", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/ruby", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "experimental", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "experimental", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "TruffleRuby linux amd64 22.1.0 jdk11 ee", - "checksum": "d20f6bf47a01ba49e2ef1f8bcd42539dc4553c3df6f0ea2b30b34db7adcbd479", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:58.623Z" - }, - { - "id": "DBD2062279363259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.espresso", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.espresso", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/java", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Java on Truffle linux amd64 22.1.0 jdk11 ee", - "checksum": "ef3cb255578552661bcdb26423a86cfad2e592d7e2a31b5898905bcd5e5d16ef", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:57.145Z" - }, - { - "id": "DBD25450B8A33307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - }, - { - "key": "requireBundle", - "value": "org.graalvm.js", - "description": "Require bundle" - }, - { - "key": "symbolicName", - "value": "org.graalvm.nodejs", - "description": "Symbolic name" - }, - { - "key": "workingDirectories", - "value": "languages/nodejs", - "description": "Working Directory" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "stabilityLevel", - "value": "supported", - "description": "Stability Level" - }, - { - "key": "stability", - "value": "supported", - "description": "Stability" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "polyglot", - "value": "True", - "description": "Polyglot part" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - } - ], - "displayName": "Graal.nodejs linux amd64 22.1.0 jdk11 ee", - "checksum": "811dc67d63a2cc34aa0ea3cf0e352a3a3dcd9cda7d1352b9e3f070da5d5b0b8f", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:55.814Z" - }, - { - "id": "DBD2062279293259E0538714000A8AC8", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(graalvm_version=22.1.0)(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "supported", - "value": "False", - "description": "Status" - }, - { - "key": "polyglot", - "value": "False", - "description": "Polyglot part" - }, - { - "key": "isBase", - "value": "False", - "description": "Artifact type" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "stability", - "value": "earlyadopter", - "description": "Stability" - }, - { - "key": "stabilityLevel", - "value": "earlyadopter", - "description": "Stability Level" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "symbolicName", - "value": "org.graalvm.native-image", - "description": "Symbolic name" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - } - ], - "displayName": "Native Image linux amd64 22.1.0 jdk11 ee", - "checksum": "59e6b4d2667450a6d5e8ef1903c31e2edb8b03d4a3743c74280e38cd64670949", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:54.450Z" - }, - { - "id": "DBD25450B89A3307E0538714000AC8BE", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "requiredCapabilities", - "value": "org.graalvm; filter:=\"(&(os_name=linux)(os_arch=amd64)(java_version=11))\"", - "description": "Required Capabilities" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "symbolicName", - "value": "org.graalvm", - "description": "Symbolic name" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - } - ], - "displayName": "GraalVM Core linux amd64 22.1.0 jdk11 ee", - "checksum": "9d9d9e09de4b2e951cf13a2a4d562bcb6a907fc824db4fe596a68454284ad3ef", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:52.777Z" - }, - { - "id": "DBD25434023B402DE0538714000ACDDC", - "licenseId": "D53D4BDFD333BFD6E0538814000A1027", - "licenseName": "Oracle Technology Network License Agreement | GraalVM Enterprise Edition", - "productId": "DBD2062278CC3259E0538714000A8AC8", - "metadata": [ - { - "key": "supported", - "value": "True", - "description": "Status" - }, - { - "key": "isBase", - "value": "True", - "description": "Artifact type" - }, - { - "key": "arch", - "value": "amd64", - "description": "Architecture" - }, - { - "key": "os", - "value": "linux", - "description": "Operating System" - }, - { - "key": "edition", - "value": "ee", - "description": "Edition" - }, - { - "key": "java", - "value": "jdk11", - "description": "Java version" - }, - { - "key": "version", - "value": "22.1.0", - "description": "Release version" - } - ], - "displayName": "GraalVM Enterprise Edition 22.1.0 on jdk11 linux amd64", - "checksum": "ea861f16278e3f6c79a77469d14c844c200bbe19afba6b63ca43b0dc4abec803", - "status": "PUBLISHED", - "timeCreated": "2022-04-04T10:09:50.895Z" - } - ] -} \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/CatalogContentsTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/CatalogContentsTest.java deleted file mode 100644 index ad9b21b3131d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/CatalogContentsTest.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Properties; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.remote.RemotePropertiesStorage; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class CatalogContentsTest extends CommandTestBase { - - public CatalogContentsTest() { - } - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "1.0.0.0"); - } - - RemotePropertiesStorage remstorage; - CatalogContents coll; - - private Version initVersion(String s) throws IOException { - Version v = Version.fromString(s); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, s); - Path catalogPath = dataFile("../repo/catalog.properties"); - Properties props = new Properties(); - try (InputStream is = Files.newInputStream(catalogPath)) { - props.load(is); - } - remstorage = new RemotePropertiesStorage(this, - getLocalRegistry(), - props, "linux_amd64", v, catalogPath.toUri().toURL()); - coll = new CatalogContents(this, remstorage, getLocalRegistry()); - return v; - } - - /** - * Checks that components for the version are provided. - */ - @Test - public void testComponentsForVersion19() throws Exception { - initVersion("1.0.0.0"); - - Collection ids = coll.getComponentIDs(); - assertTrue(ids.contains("org.graalvm.python")); - assertTrue(ids.contains("org.graalvm.ruby")); - assertTrue(ids.contains("org.graalvm.r")); - // plus graalvm - assertEquals(4, ids.size()); - - } - - @Test - public void testComponentsForVersion1901() throws Exception { - initVersion("1.0.1.0"); - Collection ids = coll.getComponentIDs(); - assertTrue(ids.contains("org.graalvm.python")); - assertTrue(ids.contains("org.graalvm.r")); - assertTrue(ids.contains("org.graalvm.ruby")); - // plus graalvm - assertEquals(4, ids.size()); - } - - @Test - public void testComponentsInLatestUpdate() throws Exception { - initVersion("1.0.1.0"); - - Version v; - v = coll.findComponent("org.graalvm.ruby").getVersion(); - assertEquals("1.0.1.1", v.toString()); - v = coll.findComponent("org.graalvm.python").getVersion(); - assertEquals("1.0.1.0", v.toString()); - v = coll.findComponent("org.graalvm.r").getVersion(); - assertEquals("1.0.1.1", v.toString()); - } - - @Test - public void testComponentsInPatchedGraal() throws Exception { - initVersion("1.0.1.1"); - - Version v; - - v = coll.findComponent("org.graalvm.ruby").getVersion(); - assertEquals("1.0.1.1", v.toString()); - v = coll.findComponent("org.graalvm.python").getVersion(); - assertEquals("1.0.1.0", v.toString()); - v = coll.findComponent("org.graalvm.r").getVersion(); - assertEquals("1.0.1.1", v.toString()); - } - - @Test - public void testComponentsForVersion191() throws Exception { - initVersion("1.1.0.0"); - - Collection ids = coll.getComponentIDs(); - assertTrue(ids.contains("org.graalvm.python")); - assertTrue(ids.contains("org.graalvm.r")); - // plus graalvm - assertEquals(3, ids.size()); - } - - /** - * Checks that the catalog will provide component versions that require to update the - * distribution for 1.0.1.0. Components in versions 1.1.x.x should be returned. - */ - @Test - public void testDistUpdateFor1901() throws Exception { - initVersion("1.0.1.0"); - coll.setAllowDistUpdate(true); - - Version v; - v = coll.findComponent("org.graalvm.ruby").getVersion(); - assertEquals("1.0.1.1", v.toString()); - v = coll.findComponent("org.graalvm.python").getVersion(); - assertEquals("1.1.0.0", v.toString()); - v = coll.findComponent("org.graalvm.r").getVersion(); - assertEquals("1.1.0.1", v.toString()); - } - - /** - * Checks that a specific version is provided. - */ - @Test - public void testSpecificVersionNoDistUpdate() throws Exception { - initVersion("1.0.1.0"); - - Version v; - Version.Match vm = Version.fromString("1.1.0.0").match(Version.Match.Type.EXACT); - ComponentInfo ci = coll.findComponent("ruby", vm); - assertNull(ci); - - vm = Version.fromString("1.0.1.0").match(Version.Match.Type.GREATER); - ci = coll.findComponent("ruby", vm); - v = ci.getVersion(); - assertEquals("1.0.1.1", v.toString()); - - vm = Version.fromString("1.0.1.0").match(Version.Match.Type.GREATER); - v = coll.findComponent("python", vm).getVersion(); - assertEquals("1.1.0.0", v.toString()); - - vm = Version.fromString("1.0.0.0").match(Version.Match.Type.EXACT); - ci = coll.findComponent("python", vm); - assertNull(ci); - - v = coll.findComponent("org.graalvm.r").getVersion(); - assertEquals("1.0.1.1", v.toString()); - - vm = Version.fromString("1.0.1.0").match(Version.Match.Type.MOSTRECENT); - v = coll.findComponent("r", vm).getVersion(); - assertEquals("1.0.1.1", v.toString()); - } - - /** - * Checks that a specific version is provided. - */ - @Test - public void testSpecificVersionDistUpdate() throws Exception { - initVersion("1.0.1.0"); - coll.setAllowDistUpdate(true); - - Version v; - Version.Match vm = Version.fromString("1.1.0.0").match(Version.Match.Type.EXACT); - ComponentInfo ci = coll.findComponent("ruby", vm); - assertNull(ci); - - vm = Version.fromString("1.0.1.0").match(Version.Match.Type.GREATER); - ci = coll.findComponent("ruby", vm); - v = ci.getVersion(); - assertEquals("1.0.1.1", v.toString()); - - vm = Version.fromString("1.0.1.0").match(Version.Match.Type.GREATER); - v = coll.findComponent("python", vm).getVersion(); - assertEquals("1.1.0.0", v.toString()); - - vm = Version.fromString("1.0.0.0").match(Version.Match.Type.EXACT); - ci = coll.findComponent("python", vm); - assertNull(ci); - - v = coll.findComponent("org.graalvm.r").getVersion(); - assertEquals("1.1.0.1", v.toString()); - - vm = Version.fromString("1.0.1.0").match(Version.Match.Type.MOSTRECENT); - v = coll.findComponent("r", vm).getVersion(); - assertEquals("1.1.0.1", v.toString()); - } - - /** - * - */ - @Test - public void testFindDependentComponents() { - - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/ComponentRegistryTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/ComponentRegistryTest.java deleted file mode 100644 index 50fa68024f4f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/ComponentRegistryTest.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.BufferedReader; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.jar.JarFile; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.commands.MockStorage; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.persist.ComponentPackageLoader; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TestName; - -public class ComponentRegistryTest extends TestBase { - private BufferedReader releaseFile; - private MockStorage mockStorage = new MockStorage(); - - private ComponentInfo rubyInfo; - private ComponentInfo fakeInfo; - private ComponentInfo tmp1; - private ComponentInfo tmp2; - - @Rule public ExpectedException exception = ExpectedException.none(); - @Rule public TestName name = new TestName(); - - private ComponentRegistry registry; - - public ComponentRegistryTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() throws Exception { - registry = new ComponentRegistry(this, mockStorage); - - try (JarFile jf = new JarFile(dataFile("truffleruby2.jar").toFile())) { - ComponentPackageLoader ldr = new JarMetaLoader(jf, this); - - rubyInfo = ldr.createComponentInfo(); - ldr.loadPaths(); - ldr.loadSymlinks(); - } - - fakeInfo = new ComponentInfo("org.graalvm.fake", "Fake component", "0.32"); - fakeInfo.addPaths(Arrays.asList( - "jre/bin/ruby", - "jre/languages/fake/nothing")); - mockStorage.installed.add(fakeInfo); - } - - private void registerAdditionalComponents() { - ComponentInfo tmp = new ComponentInfo("org.graalvm.foobar", "Test component 1", "0.32"); - mockStorage.installed.add(tmp); - - tmp = new ComponentInfo("org.graalvm.clash", "Test component 2", "0.32"); - mockStorage.installed.add(tmp); - tmp1 = tmp; - tmp = new ComponentInfo("org.github.clash", "Test component 3", "0.32"); - mockStorage.installed.add(tmp); - tmp2 = tmp; - - tmp = new ComponentInfo("org.graalvm.Uppercase", "Test component 4", "0.32"); - mockStorage.installed.add(tmp); - } - - @After - public void tearDown() throws Exception { - if (releaseFile != null) { - releaseFile.close(); - } - } - - /** - * Test of findComponent method, of class ComponentRegistry. - */ - @Test - public void testFindComponent() throws Exception { - assertSame(fakeInfo, registry.findComponent("org.graalvm.fake")); - assertNull(registry.findComponent("org.graalvm.ruby")); - - registry.addComponent(rubyInfo); - assertNotNull(registry.findComponent("org.graalvm.ruby")); - - registry.removeComponent(rubyInfo); - assertNull(registry.findComponent("org.graalvm.ruby")); - } - - @Test - public void testFindAbbreviatedComponent() throws Exception { - registerAdditionalComponents(); - - assertSame(fakeInfo, registry.findComponent("fake")); - assertNull(registry.findComponent("org.graalvm.ruby")); - assertNull(registry.findComponent("ruby")); - - assertNotNull(registry.findComponent("foobar")); - - registry.addComponent(rubyInfo); - assertNotNull(registry.findComponent("ruby")); - - registry.removeComponent(rubyInfo); - assertNull(registry.findComponent("ruby")); - } - - @Test - public void testFindAmbiguousComponent() throws Exception { - registerAdditionalComponents(); - exception.expect(FailedOperationException.class); - exception.expectMessage("COMPONENT_AmbiguousIdFound"); - registry.findComponent("clash"); - } - - @Test - public void testFindAmbiguousComponentAfterRemove() throws Exception { - registerAdditionalComponents(); - try { - registry.findComponent("clash"); - Assert.fail("Expected failure clash"); - } catch (FailedOperationException ex) { - // expected - } - registry.removeComponent(tmp2); - assertSame(tmp1, registry.findComponent("clash")); - - } - - @Test - public void testFindUnknownComponent() throws Exception { - assertSame(fakeInfo, registry.findComponent("org.graalvm.fake")); - assertNull(registry.findComponent("org.graalvm.ruby")); - } - - public void testLoadUnknownComponent() throws Exception { - - } - - /** - * Test of getComponentIDs method, of class ComponentRegistry. - */ - @Test - public void testGetComponentIDs() throws IOException { - Collection ids = registry.getComponentIDs(); - assertEquals(1, ids.size()); - assertEquals("org.graalvm.fake", ids.iterator().next()); - - registry.addComponent(rubyInfo); - - assertEquals( - new HashSet<>(Arrays.asList( - "org.graalvm.fake", - "org.graalvm.ruby")), - new HashSet<>(registry.getComponentIDs())); - - registry.removeComponent(rubyInfo); - assertEquals( - new HashSet<>(Arrays.asList( - "org.graalvm.fake")), - new HashSet<>(registry.getComponentIDs())); - } - - /** - * Test of removeComponent method, of class ComponentRegistry. - */ - @Test - public void testRemoveComponent() throws Exception { - mockStorage.installed.add(rubyInfo); - mockStorage.replacedFiles.put("jre/bin/ruby", - Arrays.asList( - "org.graalvm.fake", - "org.graalvm.ruby")); - - registry.removeComponent(rubyInfo); - Assert.assertNotEquals(mockStorage.updatedReplacedFiles, mockStorage.replacedFiles); - assertNull(mockStorage.updatedReplacedFiles.get("jre/bin/ruby")); - } - - /** - * Test of addComponent method, of class ComponentRegistry. - */ - @Test - public void testAddComponent() throws Exception { - registry.addComponent(rubyInfo); - - // check replaced files: - assertNotNull(mockStorage.updatedReplacedFiles.get("jre/bin/ruby")); - assertEquals(new HashSet<>(Arrays.asList( - "org.graalvm.fake", - "org.graalvm.ruby")), - new HashSet<>(mockStorage.updatedReplacedFiles.get("jre/bin/ruby"))); - } - - /** - * Test of getPreservedFiles method, of class ComponentRegistry. - */ - @Test - public void testGetPreservedFiles() { - mockStorage.installed.add(rubyInfo); - - List ll = registry.getPreservedFiles(rubyInfo); - assertEquals(Arrays.asList("jre/bin/ruby", CommonConstants.PATH_COMPONENT_STORAGE), ll); - } - - /** - * Test of getOwners method, of class ComponentRegistry. - */ - @Test - public void testGetOwners() { - rubyInfo.addPaths(Collections.singletonList("bin/ruby")); - mockStorage.installed.add(rubyInfo); - List l = registry.getOwners("jre/bin/ruby"); - assertEquals(new HashSet<>(Arrays.asList( - "org.graalvm.fake", - "org.graalvm.ruby")), new HashSet<>(l)); - l = registry.getOwners("bin/ruby"); - assertEquals(Arrays.asList("org.graalvm.ruby"), l); - } - - /** - * Test of isReplacedFilesChanged method, of class ComponentRegistry. - */ - @Test - public void testIsReplacedFilesChanged() throws IOException { - registry.addComponent(rubyInfo); - assertTrue(registry.isReplacedFilesChanged()); - - ComponentInfo testInfo = new ComponentInfo("org.graalvm.test", "Test component", "1.0"); - testInfo.addPaths(Arrays.asList( - "jre/bin/ruby2", - "jre/languages/fake/nothing2")); - - // add disjunct component - registry.addComponent(testInfo); - assertFalse(registry.isReplacedFilesChanged()); - } - - @Test - public void testFindUppercaseIDComponent() throws Exception { - registerAdditionalComponents(); - ComponentInfo ci = registry.findComponent("org.graalvm.Uppercase"); - assertNotNull(ci); - } - - @Test - public void testFindUppercaseIDComponentWithLowercaseExor() throws Exception { - registerAdditionalComponents(); - ComponentInfo ci = registry.findComponent("org.graalvm.uppercase"); - assertNotNull(ci); - } - - ComponentInfo ruby; - ComponentInfo fastr; - ComponentInfo llvm; - ComponentInfo image; - - private void setupComponentsWithDependencies() { - llvm = new ComponentInfo("org.graalvm.llvm-toolchain", "LLVM", Version.fromString("19.3")); - image = new ComponentInfo("org.graalvm.native-image", "Native Image", Version.fromString("19.3")); - image.setDependencies(Collections.singleton(llvm.getId())); - - fastr = new ComponentInfo("org.graalvm.r", "R", Version.fromString("19.3")); - fastr.setDependencies(Collections.singleton(llvm.getId())); - ruby = new ComponentInfo("org.graalvm.ruby", "Ruby", Version.fromString("19.3")); - ruby.setDependencies(new HashSet<>(Arrays.asList(image.getId()))); - - mockStorage.installed.add(llvm); - mockStorage.installed.add(image); - mockStorage.installed.add(fastr); - mockStorage.installed.add(ruby); - } - - @Test - public void testDependentComponents() throws Exception { - setupComponentsWithDependencies(); - - Set comps = registry.findDependentComponents(image, false); - assertEquals(1, comps.size()); - assertSame(ruby, comps.iterator().next()); - - comps = registry.findDependentComponents(llvm, false); - assertEquals(2, comps.size()); - assertTrue(comps.contains(fastr)); - assertTrue(comps.contains(image)); - } - - @Test - public void testDependentComponentsRecursive() throws Exception { - setupComponentsWithDependencies(); - - Set comps = registry.findDependentComponents(image, true); - assertEquals(1, comps.size()); - assertSame(ruby, comps.iterator().next()); - - comps = registry.findDependentComponents(llvm, true); - assertEquals(3, comps.size()); - assertTrue(comps.contains(fastr)); - assertTrue(comps.contains(ruby)); - assertTrue(comps.contains(image)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/MergedCatalogContentsTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/MergedCatalogContentsTest.java deleted file mode 100644 index 939643143f13..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/MergedCatalogContentsTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashSet; -import java.util.Properties; -import java.util.Set; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.remote.RemotePropertiesStorage; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Test; - -/** - * Tests CatalogContents which is essentially a combination of several catalogs + local registry - * contents. - * - * @author sdedic - */ -public class MergedCatalogContentsTest extends CommandTestBase { - - public MergedCatalogContentsTest() { - } - - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "1.0.0.0"); - } - - RemotePropertiesStorage remstorage; - CatalogContents coll; - - private Version initVersion(String s) throws IOException { - Version v = Version.fromString(s); - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, s); - Path catalogPath = dataFile("catalog-deps.properties"); - Properties props = new Properties(); - try (InputStream is = Files.newInputStream(catalogPath)) { - props.load(is); - } - remstorage = new RemotePropertiesStorage(this, - getLocalRegistry(), - props, "linux_amd64", v, catalogPath.toUri().toURL()); - coll = new CatalogContents(this, remstorage, getLocalRegistry()); - return v; - } - - /** - * Finds 1st level dependencies of components. - */ - @Test - public void testFindDependenciesOneLevel() throws Exception { - initVersion("19.3"); - ComponentInfo ci = coll.findComponent("org.graalvm.r", null); - assertNotNull(ci); - Set deps = new HashSet<>(); - Set errors = coll.findDependencies(ci, false, null, deps); - assertNull(errors); - assertEquals(1, deps.size()); - assertEquals("org.graalvm.llvm-toolchain", deps.iterator().next().getId()); - - ci = coll.findComponent("org.graalvm.ruby", null); - assertNotNull(ci); - deps = new HashSet<>(); - errors = coll.findDependencies(ci, false, null, deps); - assertNull(errors); - assertEquals(1, deps.size()); - assertEquals("org.graalvm.native-image", deps.iterator().next().getId()); - } - - /** - * Finds 1st level dependencies of components, but just those installed. - */ - @Test - public void testFindDependenciesOneLevelInstalled() throws Exception { - initVersion("19.3"); - ComponentInfo ci = coll.findComponent("org.graalvm.r", null); - ComponentInfo ll = coll.findComponent("org.graalvm.llvm-toolchain", null); - assertNotNull(ci); - assertNotNull(ll); - - // fake the component is local - ll.setInfoPath(""); - storage.installed.add(ll); - - Set deps = new HashSet<>(); - Set errors = coll.findDependencies(ci, false, Boolean.TRUE, deps); - assertNull(errors); - assertEquals(1, deps.size()); - assertEquals("org.graalvm.llvm-toolchain", deps.iterator().next().getId()); - - // native-image is not local, will be reported as broken: - ci = coll.findComponent("org.graalvm.ruby", null); - assertNotNull(ci); - deps = new HashSet<>(); - errors = coll.findDependencies(ci, false, Boolean.TRUE, deps); - assertNotNull(errors); - assertTrue(deps.isEmpty()); - assertEquals(1, errors.size()); - assertEquals("org.graalvm.native-image", errors.iterator().next()); - } - - /** - * Finds components recursively. - */ - @Test - public void testFindDependenciesRecursive() throws Exception { - initVersion("19.3"); - ComponentInfo ci = coll.findComponent("org.graalvm.r", null); - assertNotNull(ci); - Set deps = new HashSet<>(); - Set errors = coll.findDependencies(ci, true, null, deps); - assertNull(errors); - assertEquals(1, deps.size()); - assertEquals("org.graalvm.llvm-toolchain", deps.iterator().next().getId()); - - ci = coll.findComponent("org.graalvm.ruby", null); - assertNotNull(ci); - deps = new HashSet<>(); - errors = coll.findDependencies(ci, true, null, deps); - assertNull(errors); - assertEquals(2, deps.size()); - - ComponentInfo ni = coll.findComponent("org.graalvm.native-image", null); - ComponentInfo ll = coll.findComponent("org.graalvm.llvm-toolchain", null); - assertTrue(deps.contains(ni)); - assertTrue(deps.contains(ll)); - } - - /** - * Checks that installed components from the closure are reported and those not installed are - * reported as missing in the return val. - */ - @Test - public void testFindDependenciesRecursiveInstalled() throws Exception { - initVersion("19.3"); - ComponentInfo ci = coll.findComponent("org.graalvm.ruby", null); - ComponentInfo ni = coll.findComponent("org.graalvm.native-image", null); - assertNotNull(ci); - assertNotNull(ni); - ni.setInfoPath(""); - storage.installed.add(ni); - - Set deps = new HashSet<>(); - Set errors = coll.findDependencies(ci, true, Boolean.TRUE, deps); - assertNotNull(errors); - assertEquals(1, deps.size()); - assertEquals(1, errors.size()); - assertEquals("org.graalvm.native-image", deps.iterator().next().getId()); - assertEquals("org.graalvm.llvm-toolchain", errors.iterator().next()); - } - - /** - * Checks that only not installed dependencies are reported. One is installed and will not be - * returned (but is present). The other is not yet installed, will be reported. - */ - @Test - public void testFindDependenciesOnlyMissing() throws Exception { - initVersion("19.3"); - ComponentInfo ci = coll.findComponent("org.graalvm.ruby", null); - ComponentInfo ni = coll.findComponent("org.graalvm.native-image", null); - assertNotNull(ci); - assertNotNull(ni); - ni.setInfoPath(""); - storage.installed.add(ni); - - Set deps = new HashSet<>(); - Set errors = coll.findDependencies(ci, true, Boolean.FALSE, deps); - assertNull(errors); - assertEquals(1, deps.size()); - assertEquals("org.graalvm.llvm-toolchain", deps.iterator().next().getId()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/VerifierTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/VerifierTest.java deleted file mode 100644 index eb35bdccdbdc..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/VerifierTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.util.jar.JarFile; -import static org.graalvm.component.installer.CommonConstants.CAP_OS_NAME; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.commands.MockStorage; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.persist.ComponentPackageLoader; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * - * @author sdedic - */ -public class VerifierTest extends TestBase { - private MockStorage mockStorage = new MockStorage(); - private ComponentRegistry registry; - private ComponentInfo rubyInfo; - - @Rule public ExpectedException exception = ExpectedException.none(); - - @Before - public void setUp() throws Exception { - registry = new ComponentRegistry(this, mockStorage); - } - - @Test - public void testGraalCapabilitiesCaseInsensitive() throws Exception { - try (JarFile jf = new JarFile(dataFile("truffleruby2.jar").toFile())) { - ComponentPackageLoader ldr = new JarMetaLoader(jf, this); - - rubyInfo = ldr.createComponentInfo(); - ldr.loadPaths(); - ldr.loadSymlinks(); - } - mockStorage.graalInfo.put(CAP_OS_NAME, "LiNuX"); - - Verifier vfy = new Verifier(this, registry, registry); - vfy.validateRequirements(rubyInfo); - } - - @Test - public void testGraalCapabilitiesMismatch() throws Exception { - try (JarFile jf = new JarFile(dataFile("truffleruby2.jar").toFile())) { - ComponentPackageLoader ldr = new JarMetaLoader(jf, this); - - rubyInfo = ldr.createComponentInfo(); - ldr.loadPaths(); - ldr.loadSymlinks(); - } - mockStorage.graalInfo.put(CAP_OS_NAME, "LiNuy"); - - Verifier vfy = new Verifier(this, registry, registry); - exception.expect(DependencyException.Mismatch.class); - exception.expectMessage("VERIFY_Dependency_Failed"); - vfy.validateRequirements(rubyInfo); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/catalog-deps.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/catalog-deps.properties deleted file mode 100644 index be482adf3d07..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/catalog-deps.properties +++ /dev/null @@ -1,41 +0,0 @@ -org.graalvm.19.3_linux_amd64=GraalVM 19.3 linux/amd64 - -Component.linux_amd64/19.3/org.graalvm.llvm_toolchain=llvm/19.3 -Component.linux_amd64/19.3/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/19.3/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3/org.graalvm.llvm_toolchain-Bundle-Name=LLVM Toolchain -Component.linux_amd64/19.3/org.graalvm.llvm_toolchain-Bundle-Version=19.3 - -Component.linux_amd64/19.3/org.graalvm.native_image=image/19.3 -Component.linux_amd64/19.3/org.graalvm.native_image-Bundle-Symbolic-Name=org.graalvm.native-image -Component.linux_amd64/19.3/org.graalvm.native_image-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3/org.graalvm.native_image-Bundle-Name=Native Image -Component.linux_amd64/19.3/org.graalvm.native_image-Bundle-Version=19.3 -Component.linux_amd64/19.3/org.graalvm.native_image-Require-Bundle=org.graalvm.llvm-toolchain - -Component.linux_amd64/19.3/org.graalvm.broken=broken/19.3 -Component.linux_amd64/19.3/org.graalvm.broken-Bundle-Symbolic-Name=org.graalvm.broken -Component.linux_amd64/19.3/org.graalvm.broken-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3/org.graalvm.broken-Bundle-Name=Broken Component -Component.linux_amd64/19.3/org.graalvm.broken-Bundle-Version=19.3 -Component.linux_amd64/19.3/org.graalvm.broken-Require-Bundle=org.graalvm.missing1 - -Component.linux_amd64/19.3/org.graalvm.r=r/19.3 -Component.linux_amd64/19.3/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/19.3/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/19.3/org.graalvm.r-Bundle-Version=19.3 -Component.linux_amd64/19.3/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain - -Component.linux_amd64/19.3/org.graalvm.ruby=ruby/19.3 -Component.linux_amd64/19.3/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/19.3/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/19.3/org.graalvm.ruby-Bundle-Version=19.3 -Component.linux_amd64/19.3/org.graalvm.ruby-Require-Bundle=org.graalvm.native-image - -Component.linux_amd64/19.3/org.graalvm=core/graalvm-19.3.jar -Component.linux_amd64/19.3/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/19.3/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/19.3/org.graalvm-Bundle-Version=19.3 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/truffleruby2.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/model/truffleruby2.jar deleted file mode 100644 index 2548701139861ee3189183c7afcdec038842cfa0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113113 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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 F{{S}{r&Is{ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/Bundle.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/Bundle.properties deleted file mode 100644 index 2ae778bfb9d8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/Bundle.properties +++ /dev/null @@ -1,30 +0,0 @@ -# {0} - component ID -# {1} - component version -LICENSE_Path_translation=LICENSE-{0}-{1} -ERROR_HeaderMissing=ERROR_HeaderMissing -ERROR_MissingSymbolicName=ERROR_MissingSymbolicName -ERROR_InvalidSymbolicName=ERROR_InvalidSymbolicName -ERROR_ParametersUnsupported=ERROR_ParametersUnsupported -ERROR_InvalidVersion=ERROR_InvalidVersion -ERROR_InvalidCapabilityName=ERROR_InvalidCapabilityName -ERROR_MissingCapabilityName=ERROR_MissingCapabilityName -# {0} - Directive or parameter name -ERROR_MissingArgument=ERROR_MissingArgument -# {0} - parameter name -ERROR_InvalidParameterSyntax=ERROR_InvalidParameterSyntax -ERROR_InvalidQuotedString=ERROR_InvalidQuotedString -# {0} - parameter name -ERROR_MissingArgument=ERROR_MissingArgument -ERROR_InvalidVersion=ERROR_InvalidVersion -ERROR_InvalidParameterName=ERROR_InvalidParameterName -ERROR_UnsupportedParameters=ERROR_UnsupportedParameters -ERROR_UnsupportedDirectives=ERROR_UnsupportedDirectives -ERROR_MissingVersionFilter=ERROR_MissingVersionFilter -ERROR_InvalidFilterSpecification=ERROR_InvalidFilterSpecification -ERROR_UnknownCapability=ERROR_UnknownCapability -ERROR_UnsupportedFilterOperation=ERROR_UnsupportedFilterOperation -ERROR_DuplicateFilterAttribute=ERROR_DuplicateFilterAttribute - -ERROR_PermissionFormat=ERROR_PermissionFormat -ERROR_BrokenSymlink=ERROR_BrokenSymlink -ERROR_CircularSymlink=ERROR_CircularSymlink diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ComponentPackageLoaderTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ComponentPackageLoaderTest.java deleted file mode 100644 index ddac9c4d27c6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ComponentPackageLoaderTest.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.BufferedReader; -import org.graalvm.component.installer.MetadataException; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.jar.JarFile; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.model.StabilityLevel; -import org.junit.After; -import org.junit.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.ExternalResource; -import org.junit.rules.TestName; - -public class ComponentPackageLoaderTest extends TestBase { - @Rule public TestName name = new TestName(); - @Rule public ExpectedException exception = ExpectedException.none(); - private Properties data = new Properties(); - private JarFile jarData; - - public ComponentPackageLoaderTest() { - } - - private JarFile jf; - - @Rule public ExternalResource jarFileResource = new ExternalResource() { - @Override - protected void after() { - if (jf != null) { - try { - jf.close(); - } catch (IOException ex) { - // ignore - } - } - super.after(); - } - }; - - @Before - public void setUp() throws Exception { - defaultBundle = ResourceBundle.getBundle("org.graalvm.component.installer.persist.Bundle"); // NOI18N - String s = name.getMethodName(); - if (s.startsWith("test") && s.length() > 4) { - s = Character.toLowerCase(s.charAt(4)) + s.substring(5); - } - - Path dp = dataFile("data/" + s + ".jar"); - if (Files.exists(dp)) { - this.jarData = new JarFile(dp.toFile()); - } - try (InputStream istm = getClass().getResourceAsStream("data/" + s + ".properties")) { - if (istm != null) { - data.load(istm); - } - } - } - - @After - public void tearDown() throws Exception { - if (jarData != null) { - jarData.close(); - } - } - - ComponentInfo info() throws IOException { - if (jarData == null) { - return new ComponentPackageLoader(data::getProperty, this).createComponentInfo(); - } else { - return new JarMetaLoader(jarData, this).createComponentInfo(); - } - } - - /** - * Checks that the parser rejects components, if they have some keys required. - * - * @throws Exception - */ - @Test - @SuppressWarnings({"rawtypes", "unchecked"}) - public void testRequiredKeys() throws Exception { - // first try to parse OK to capture possibel bugs - info(); - - Properties save = new Properties(); - save.putAll(this.data); - List sorted = new ArrayList<>((Set) save.keySet()); - Collections.sort(sorted); - for (String s : save.stringPropertyNames()) { - data = new Properties(); - data.putAll(save); - data.remove(s); - - try { - info(); - Assert.fail("Pasrer must reject component without key " + s); - } catch (MetadataException ex) { - // OK - } - } - } - - @Test - public void testWorkingDirectories() throws Exception { - // first try to parse OK to capture possibel bugs - info = info(); - - assertTrue(info.getWorkingDirectories().contains("jre/languages/test/scrap")); - assertTrue(info.getWorkingDirectories().contains("jre/lib/test/scrapdir")); - } - - @Test - public void testCollectErrors() throws Exception { - File f = dataFile("broken1.zip").toFile(); - jf = new JarFile(f); - loader = new JarMetaLoader(jf, this).infoOnly(true); - info = loader.createComponentInfo(); - - List errs = new ArrayList<>(); - loader.getErrors().forEach((e) -> errs.add(((MetadataException) e).getOffendingHeader())); - Collections.sort(errs); - assertEquals("org.graalvm.ruby", info.getId()); - assertEquals(Arrays.asList( - BundleConstants.BUNDLE_NAME, - BundleConstants.BUNDLE_REQUIRED, - BundleConstants.BUNDLE_VERSION), errs); - } - - private ComponentPackageLoader loader; - private ComponentInfo info; - - private void setupLoader() throws IOException { - File f = dataFile("data/truffleruby2.jar").toFile(); - jf = new JarFile(f); - loader = new JarMetaLoader(jf, this); - info = loader.createComponentInfo(); - } - - @Test - public void testLoadPaths() throws Exception { - setupLoader(); - assertTrue(info.getPaths().isEmpty()); - loader.loadPaths(); - assertFalse(info.getPaths().isEmpty()); - assertTrue(info.getPaths().contains("jre/bin/ruby")); - } - - @Test - public void testLoadSymlinks() throws Exception { - setupLoader(); - loader.loadPaths(); - Map slinks = loader.loadSymlinks(); - assertNotNull(slinks); - assertNotNull(slinks.get("bin/ruby")); - - // check that empty symlink props parse to nothing: - loader.parseSymlinks(new Properties()); - } - - @Test - public void testComponetInfoFromJar() throws Exception { - setupLoader(); - assertNotNull(info.getId()); - assertEquals("1.0", info.getVersionString()); - - Map caps = info.getRequiredGraalValues(); - assertNotNull(caps); - assertNotNull(caps.get(CommonConstants.CAP_GRAALVM_VERSION)); - } - - @Test - public void testParseChainedSymlinks() throws Exception { - setupLoader(); - loader.loadPaths(); - - Properties links = new Properties(); - try (InputStream istm = new FileInputStream(dataFile("chainedSymlinks.properties").toFile())) { - links.load(istm); - } - - loader.parseSymlinks(links); - } - - @Test - public void testParseCircularSymlink() throws Exception { - setupLoader(); - loader.loadPaths(); - - Properties links = new Properties(); - try (InputStream istm = new FileInputStream(dataFile("circularSymlinks.properties").toFile())) { - links.load(istm); - } - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_CircularSymlink"); - loader.parseSymlinks(links); - } - - @Test - public void testBrokenSymlink() throws Exception { - setupLoader(); - loader.loadPaths(); - - Properties links = new Properties(); - try (InputStream istm = new FileInputStream(dataFile("brokenSymlinks.properties").toFile())) { - links.load(istm); - } - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_BrokenSymlink"); - loader.parseSymlinks(links); - } - - @Test - public void testBrokenChainedSymlink() throws Exception { - setupLoader(); - loader.loadPaths(); - - Properties links = new Properties(); - try (InputStream istm = new FileInputStream(dataFile("brokenChainedSymlinks.properties").toFile())) { - links.load(istm); - } - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_BrokenSymlink"); - loader.parseSymlinks(links); - } - - @Test - public void testLoadInvalidPermssions() throws Exception { - setupLoader(); - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_PermissionFormat"); - try (InputStream istm = Files.newInputStream(dataFile("brokenPermissions.properties")); - BufferedReader br = new BufferedReader(new InputStreamReader(istm))) { - loader.parsePermissions(br); - } - } - - @Test - public void testLoadPermssions() throws Exception { - setupLoader(); - Map permissions = loader.loadPermissions(); - - String v = permissions.get("./jre/languages/ruby/bin/gem"); - assertEquals("", v); - v = permissions.get("./jre/bin/ruby"); - assertEquals("r-xr-xr-x", v); - } - - @Test - public void testPostinstMessage() throws Exception { - // first try to parse OK to capture possibel bugs - info = info(); - String[] slashes = info.getPostinstMessage().split("\\\\"); - assertEquals(3, slashes.length); - String[] lines = info.getPostinstMessage().split("\n"); - assertEquals(4, lines.length); - } - - @Test - public void testFastr() throws Exception { - info = info(); - assertEquals(1, info.getDependencies().size()); - assertEquals("org.graalvm.llvm-toolchain", info.getDependencies().iterator().next()); - } - - @Test - public void testDistributionTypeMissing() throws Exception { - info = info(); - assertEquals(DistributionType.OPTIONAL, info.getDistributionType()); - } - - @Test - public void testDistributionTypeBundled() throws Exception { - info = info(); - assertEquals(DistributionType.BUNDLED, info.getDistributionType()); - } - - @Test - public void testDistributionTypeInvalid() throws Exception { - info = info(); - assertEquals(DistributionType.OPTIONAL, info.getDistributionType()); - } - - /** - * Checks the old attribute is still read/honoured. - * - * @throws Exception - */ - @Test - public void testStabilityOld() throws Exception { - info = info(); - assertEquals(StabilityLevel.Experimental, info.getStability()); - } - - /** - * Checks the new attribute is read. - */ - @Test - public void testStabilityNew() throws Exception { - info = info(); - assertEquals(StabilityLevel.Experimental_Earlyadopter, info.getStability()); - } - - /** - * Checks the if new AND old attributes are present, the new one gets precedence. - */ - @Test - public void testStabilityPrecedence() throws Exception { - info = info(); - assertEquals(StabilityLevel.Experimental, info.getStability()); - } - - @Test - public void testStabilityLevelNone() throws Exception { - info = info(); - assertEquals(StabilityLevel.Undefined, info.getStability()); - assertNotNull(info.getStability().displayName(this)); - } - - @Test - public void testStabilityLevelUnknown() throws Exception { - info = info(); - assertEquals(StabilityLevel.Undefined, info.getStability()); - assertNotNull(info.getStability().displayName(this)); - } - - @Test - public void testStabilityLevelExperimental() throws Exception { - info = info(); - assertEquals(StabilityLevel.Experimental, info.getStability()); - assertNotNull(info.getStability().displayName(this)); - } - - @Test - public void testStabilityLevelExperimental2() throws Exception { - info = info(); - assertEquals(StabilityLevel.Experimental_Earlyadopter, info.getStability()); - assertNotNull(info.getStability().displayName(this)); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryCatalogProviderTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryCatalogProviderTest.java deleted file mode 100644 index 41910f4f28d2..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryCatalogProviderTest.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.test.Handler; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class DirectoryCatalogProviderTest extends CommandTestBase { - @Rule public ProxyResource proxyResource = new ProxyResource(); - - @Test - public void testLoadFromEmptyDirectory() throws Exception { - Path nf = testFolder.newFolder().toPath(); - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(nf, this); - - assertTrue(prov.listComponentIDs().isEmpty()); - } - - @Test - public void testLoadFromNonDirectory() throws Exception { - Path nf = testFolder.newFile().toPath(); - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(nf, this); - - assertTrue(prov.listComponentIDs().isEmpty()); - } - - @Test - public void testLoadComponentsJars() throws Exception { - Path ruby033 = dataFile("data/truffleruby2.jar"); - Path ruby10 = dataFile("../remote/data/truffleruby2.jar"); - Path llvm = dataFile("data/llvm-toolchain.jar"); - - Path nf = testFolder.newFolder().toPath(); - Files.copy(ruby033, nf.resolve(ruby033.getFileName())); - Files.copy(ruby10, nf.resolve("truffleruby10.jar")); - Files.copy(llvm, nf.resolve(llvm.getFileName())); - - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(nf, this); - Set ids = prov.listComponentIDs(); - - assertEquals(2, ids.size()); - assertTrue(ids.contains("org.graalvm.ruby")); - assertTrue(ids.contains("org.graalvm.llvm-toolchain")); - } - - static class E { - Throwable ex; - String file; - String msg; - } - - class FB extends FeedbackAdapter { - List errs = new ArrayList<>(); - - @Override - public void error(String key, Throwable t, Object... params) { - E e = new E(); - e.ex = t; - if (params != null && params.length > 1) { - e.file = Objects.toString(params[0]); - e.msg = Objects.toString(params[1]); - } - errs.add(e); - } - } - - /** - * Checks that invalid/non-components/broken stuff is reported. When the user specifies - * directory as catalog source, it's probably important to report invalid data. - */ - @Test - public void testReportBrokenComponents() throws Exception { - Path testData = dataFile("dir1"); - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(testData, this); - FB fb = new FB(); - delegateFeedback(fb); - - Set ids = prov.listComponentIDs(); - assertEquals(2, ids.size()); - assertEquals(3, fb.errs.size()); - } - - /** - * Implied directory catalogs (to resolve dependencies) can scan directories with random - * contents. broken or non-components should be silently ignored. - */ - @Test - public void testSuppressErrorComponents() throws Exception { - Path testData = dataFile("dir1"); - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(testData, this); - prov.setReportErrors(false); - FB fb = new FB(); - delegateFeedback(fb); - - Set ids = prov.listComponentIDs(); - assertEquals(2, ids.size()); - assertTrue(fb.errs.isEmpty()); - } - - @Test - public void testDifferentRequirementsFiltered() throws Exception { - Path testData = dataFile("dir1"); - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(testData, this); - Set ids = prov.listComponentIDs(); - assertEquals(2, ids.size()); - // typo is there... - Collection infos = prov.loadComponentMetadata("org.graavm.ruby"); - assertEquals(2, infos.size()); - - CatalogContents contents = new CatalogContents(this, prov, getLocalRegistry()); - Version.Match m = getLocalRegistry().getGraalVersion().match(Version.Match.Type.INSTALLABLE); - - // check that the JDK11 component gets removed - Collection catInfos = contents.loadComponents("org.graavm.ruby", m, false); - assertEquals(1, catInfos.size()); - - ComponentInfo ci = catInfos.iterator().next(); - assertEquals(testData.resolve("ruby.jar").toUri().toURL(), ci.getRemoteURL()); - } - - @Test - public void testSpecificJavaPresent() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_JAVA_VERSION, "11"); - Path testData = dataFile("dir1"); - DirectoryCatalogProvider prov = new DirectoryCatalogProvider(testData, this); - Set ids = prov.listComponentIDs(); - assertEquals(2, ids.size()); - // typo is there... - Collection infos = prov.loadComponentMetadata("org.graavm.ruby"); - assertEquals(2, infos.size()); - - CatalogContents contents = new CatalogContents(this, prov, getLocalRegistry()); - Version.Match m = getLocalRegistry().getGraalVersion().match(Version.Match.Type.INSTALLABLE); - - // both Ruby should pass: ruby.jar has no jdk restriction - Collection catInfos = contents.loadComponents("org.graavm.ruby", m, false); - assertEquals(2, catInfos.size()); - - Set urls = new HashSet<>(Arrays.asList( - testData.resolve("ruby.jar").toUri().toURL(), - testData.resolve("ruby-11.jar").toUri().toURL())); - Iterator itC = catInfos.iterator(); - ComponentInfo ci = itC.next(); - assertTrue(urls.remove(ci.getRemoteURL())); - ci = itC.next(); - assertTrue(urls.remove(ci.getRemoteURL())); - } - - /** - * Checks that the merging catalog initializes the directory provider correctly. - * - * @throws Exception - */ - @Test - public void testNoErrorsWithLocalCatalogs() throws Exception { - URL clu = getClass().getResource("data/catalog"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - clu); - - Path testData = dataFile("dir1"); - SoftwareChannelSource scs = new SoftwareChannelSource(testData.toUri().toURL().toString(), "local dir"); - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - - FB fb = new FB(); - delegateFeedback(fb); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - d.addLocalChannelSource(scs); - registry = openCatalog(d); - - // directory contents scanned / component found - ComponentInfo info = registry.findComponent("org.graalvm.llvm-toolchain"); - assertNotNull(info); - // catalog loaded / component found - info = registry.findComponent("ruby"); - assertNotNull(info); - - // no errors - assertTrue(fb.errs.isEmpty()); - } - - ComponentCatalog openCatalog(SoftwareChannel ch) throws IOException { - return openCatalog(ch, getLocalRegistry().getGraalVersion()); - } - - ComponentCatalog openCatalog(SoftwareChannel ch, Version v) throws IOException { - ComponentCatalog cc = new CatalogContents(this, ch.getStorage(), getLocalRegistry(), v); - cc.getComponentIDs(); - return cc; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryChannelFactoryTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryChannelFactoryTest.java deleted file mode 100644 index 222e39c3446e..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryChannelFactoryTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.GraalEdition; -import org.graalvm.component.installer.remote.RemoteCatalogDownloader; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class DirectoryChannelFactoryTest extends CommandTestBase implements CommandInput.CatalogFactory { - RemoteCatalogDownloader downloader; - - @Test - public void testEmptyDownloaderProducesNothing() throws Exception { - downloader = new RemoteCatalogDownloader(this, this, (URL) null); - - ComponentInfo info = getRegistry().findComponent("org.graalvm.ruby"); - assertNull(info); - } - - @Test - public void testLoadFromEmptyDirectory() throws Exception { - Path nf = testFolder.newFolder().toPath(); - Path ruby033 = dataFile("data/truffleruby3.jar"); - Files.copy(ruby033, nf.resolve(ruby033.getFileName())); - // truffleruby3 declares that version - storage.graalInfo.put(BundleConstants.GRAAL_VERSION, "0.33-dev"); - - downloader = new RemoteCatalogDownloader(this, this, (URL) null); - SoftwareChannelSource scs = new SoftwareChannelSource(nf.toUri().toString()); - downloader.addLocalChannelSource(scs); - - ComponentInfo info = getRegistry().findComponent("ruby"); - assertNotNull(info); - } - - @Override - public ComponentCatalog createComponentCatalog(CommandInput input) { - return new CatalogContents(this, downloader.getStorage(), getLocalRegistry()); - } - - @Override - public CatalogFactory getCatalogFactory() { - return this; - } - - @Override - public List listEditions(ComponentRegistry targetGraalVM) { - return Collections.emptyList(); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryMetaLoader.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryMetaLoader.java deleted file mode 100644 index c641c886a9da..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryMetaLoader.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UncheckedIOException; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.jar.Manifest; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.graalvm.component.installer.Archive; -import static org.graalvm.component.installer.BundleConstants.META_INF_PATH; -import static org.graalvm.component.installer.BundleConstants.META_INF_PERMISSIONS_PATH; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.junit.Assert; - -/** - * - * @author sdedic - */ -public final class DirectoryMetaLoader extends ComponentPackageLoader { - private final Path rootDir; - private Manifest mani; - - private DirectoryMetaLoader(Path rootDir, Function supplier, Feedback feedback) { - super(supplier, feedback); - this.rootDir = rootDir; - } - - private Manifest getManifest() { - if (mani != null) { - return mani; - } - try (InputStream istm = Files.newInputStream(rootDir.resolve(Paths.get("META-INF", "MANIFEST.MF")))) { - mani = new Manifest(istm); - } catch (IOException ex) { - Assert.fail("Failure reading manifest"); - } - return mani; - } - - public static DirectoryMetaLoader create(Path rotoDir, Feedback feedback) { - ManifestValues vv = new ManifestValues(); - DirectoryMetaLoader ldr = new DirectoryMetaLoader(rotoDir, vv, feedback); - vv.loader = ldr; - return ldr; - } - - private static class ManifestValues implements Function { - private DirectoryMetaLoader loader; - - ManifestValues() { - } - - @Override - public String apply(String t) { - return loader.getManifest().getMainAttributes().getValue(t); - } - } - - @Override - public void loadPaths() { - ComponentInfo cinfo = getComponentInfo(); - Set emptyDirectories = new HashSet<>(); - List files = new ArrayList<>(); - - try { - Files.walk(rootDir).forEachOrdered((Path en) -> { - String eName = SystemUtils.toCommonPath(en); - if (eName.startsWith(META_INF_PATH)) { - return; - } - int li = eName.lastIndexOf("/", Files.isDirectory(en) ? eName.length() - 2 : eName.length() - 1); - if (li > 0) { - emptyDirectories.remove(eName.substring(0, li + 1)); - } - if (Files.isDirectory(en)) { - // directory names always come first - emptyDirectories.add(eName); - } else { - files.add(eName); - } - }); - addFiles(new ArrayList<>(emptyDirectories)); - // sort empty directories first - Collections.sort(files); - cinfo.addPaths(files); - addFiles(files); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } - - @Override - public Map loadSymlinks() throws IOException { - return super.loadSymlinks(); // To change body of generated methods, choose Tools | - // Templates. - } - - @Override - public Map loadPermissions() throws IOException { - Path permissionsPath = rootDir.resolve(SystemUtils.fromCommonRelative(META_INF_PERMISSIONS_PATH)); - if (!Files.exists(permissionsPath)) { - return Collections.emptyMap(); - } - try (BufferedReader r = new BufferedReader(new InputStreamReader( - Files.newInputStream(permissionsPath), "UTF-8"))) { - Map permissions = parsePermissions(r); - return permissions; - } - } - - @Override - public String getLicenseID() { - return super.getLicenseID(); // To change body of generated methods, choose Tools | - // Templates. - } - - public class FE implements Archive.FileEntry { - private final Path path; - - public FE(Path p) { - this.path = p; - } - - @Override - public String getName() { - return SystemUtils.toCommonPath(rootDir.relativize(path)); - } - - @Override - public boolean isDirectory() { - return Files.isDirectory(path); - } - - @Override - public boolean isSymbolicLink() { - return Files.isSymbolicLink(path); - } - - @Override - public String getLinkTarget() throws IOException { - return SystemUtils.toCommonPath(Files.readSymbolicLink(path)); - } - - @Override - public long getSize() { - try { - return Files.size(path); - } catch (IOException ex) { - return -1; - } - } - - } - - public class DirArchive implements Archive { - public DirArchive() { - } - - @Override - public InputStream getInputStream(FileEntry e) throws IOException { - return Files.newInputStream(((FE) e).path); - } - - @Override - public boolean checkContentsMatches(ReadableByteChannel bc, FileEntry entry) throws IOException { - return true; - } - - @Override - public boolean verifyIntegrity(CommandInput input) throws IOException { - return true; - } - - @Override - public void completeMetadata(ComponentInfo info) throws IOException { - } - - @Override - public void close() throws IOException { - } - - @Override - public Iterator iterator() { - Stream stream; - try { - stream = Files.walk(rootDir).sequential(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - return stream.filter((t) -> !rootDir.resolve(t).equals(rootDir)).map((p) -> (Archive.FileEntry) new FE(p)).collect(Collectors.toList()).iterator(); - } - - } - - @Override - public Archive getArchive() { - return new DirArchive(); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryStorageTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryStorageTest.java deleted file mode 100644 index 1c8e91dbee81..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/DirectoryStorageTest.java +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.PosixFileAttributeView; -import java.nio.file.attribute.PosixFilePermissions; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.stream.Collectors; - -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.model.StabilityLevel; -import org.junit.After; -import org.junit.AfterClass; -import static org.junit.Assert.assertNotNull; -import org.junit.Assume; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.junit.rules.TestName; - -public class DirectoryStorageTest extends CommandTestBase { - @Rule public TestName name = new TestName(); - @Rule public TemporaryFolder workDir = new TemporaryFolder(); - @Rule public ExpectedException exception = ExpectedException.none(); - - private DirectoryStorage storage; - private Path registryPath; - private Path graalVMPath; - - public DirectoryStorageTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - graalVMPath = workDir.newFolder("graal").toPath(); - Files.createDirectory(graalVMPath.resolve("bin")); - registryPath = workDir.newFolder("registry").toPath(); - - storage = new DirectoryStorage(this, registryPath, graalVMPath); - // the default assumed by most test data. - storage.setJavaVersion("8"); - } - - @After - public void tearDown() { - } - - /** - * Test of loadGraalVersionInfo method, of class RegistryStorage. - */ - @Test - public void testLoadGraalVersionSimple() throws Exception { - try (InputStream is = getClass().getResourceAsStream("release_simple.properties")) { - Files.copy(is, graalVMPath.resolve(SystemUtils.fileName("release"))); - } - Map result = storage.loadGraalVersionInfo(); - assertEquals(7, result.size()); - assertEquals(CommonConstants.EDITION_CE, result.get(CommonConstants.CAP_EDITION)); - } - - @Test - public void testLoadGraalVersionSimpleEE() throws Exception { - try (InputStream is = getClass().getResourceAsStream("release_ee_simple.properties")) { - Files.copy(is, graalVMPath.resolve(SystemUtils.fileName("release"))); - } - Map result = storage.loadGraalVersionInfo(); - assertEquals(7, result.size()); - assertEquals("ee", result.get(CommonConstants.CAP_EDITION)); - } - - @Test - public void testFailToLoadReleaseFile() throws Exception { - exception.expect(FailedOperationException.class); - Map result = storage.loadGraalVersionInfo(); - assertEquals(7, result.size()); - } - - @Test - public void testLoadReleaseWithInvalidSourceVersions() throws Exception { - try (InputStream is = getClass().getResourceAsStream("release_noVersion.properties")) { - Files.copy(is, graalVMPath.resolve(SystemUtils.fileName("release"))); - } - exception.expect(FailedOperationException.class); - exception.expectMessage("STORAGE_InvalidReleaseFile"); - - storage.loadGraalVersionInfo(); - } - - @Test - public void testLoadGraalVersionCorrupted() throws Exception { - try (InputStream is = getClass().getResourceAsStream("release_corrupted.properties")) { - Files.copy(is, graalVMPath.resolve(SystemUtils.fileName("release"))); - } - exception.expect(FailedOperationException.class); - exception.expectMessage("STORAGE_InvalidReleaseFile"); - storage.loadGraalVersionInfo(); - } - - @Test - public void testLoadMetadata() throws Exception { - Path p = dataFile("list1/fastr.component"); - ComponentInfo info; - - try (InputStream is = Files.newInputStream(p)) { - info = storage.loadMetadataFrom(is); - } - assertEquals("org.graalvm.fastr", info.getId()); - assertEquals("1.0", info.getVersionString()); - assertEquals("0.32", info.getRequiredGraalValues().get("graalvm_version")); - } - - @Test - public void testLoadProvidedCapabilities() throws Exception { - Path p = dataFile("data/core1.component"); - ComponentInfo info; - - try (InputStream is = Files.newInputStream(p)) { - info = storage.loadMetadataFrom(is); - } - assertEquals("org.graalvm", info.getId()); - assertEquals(Version.fromString("1.0.1.0"), info.getProvidedValue("version", Version.class)); - assertEquals("ee", info.getProvidedValue("edition", String.class)); - } - - /** - * Test of listComponentIDs method, of class RegistryStorage. - */ - @Test - public void testListComponentsSimple() throws Exception { - copyDir("list1", registryPath); - List comps = new ArrayList<>(storage.listComponentIDs()); - Collections.sort(comps); - comps.remove(BundleConstants.GRAAL_COMPONENT_ID); - assertEquals(Arrays.asList("fastr", "fastr-2", "ruby", "sulong"), comps); - } - - @Test - public void testListComponentsEmpty() throws Exception { - copyDir("emptylist", registryPath); - List comps = new ArrayList<>(storage.listComponentIDs()); - comps.remove(BundleConstants.GRAAL_COMPONENT_ID); - assertEquals(Collections.emptyList(), comps); - } - - private ComponentInfo loadLastComponent(String id) throws IOException { - Set infos = storage.loadComponentMetadata(id); - if (infos == null || infos.isEmpty()) { - return null; - } - List sorted = new ArrayList<>(infos); - Collections.sort(sorted, ComponentInfo.versionComparator()); - return sorted.get(sorted.size() - 1); - } - - /** - * Test of loadComponentMetadata method, of class RegistryStorage. - */ - @Test - public void testLoadComponentMetadata() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - assertEquals("org.graalvm.fastr", info.getId()); - assertEquals("1.0", info.getVersionString()); - assertEquals("0.32", info.getRequiredGraalValues().get("graalvm_version")); - } - - /** - * Test of loadComponentMetadata method, of class RegistryStorage. - */ - @Test - public void testLoadComponentMetadata2() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr-2"); - assertEquals("org.graalvm.fastr", info.getId()); - - assertTrue(info.getWorkingDirectories().contains("jre/languages/test/scrap")); - assertTrue(info.getWorkingDirectories().contains("jre/lib/test/scrapdir")); - } - - /** - * Should strip whitespaces around. - * - * @throws Exception - */ - @Test - public void loadComponentFiles() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - storage.loadComponentFiles(info); - List paths = info.getPaths(); - assertEquals(Arrays.asList( - "bin/", "bin/R", "bin/Rscript"), paths.subList(0, 3)); - } - - /** - * Should strip whitespaces around. - * - * @throws Exception - */ - @Test - public void loadComponentFilesMissing() throws Exception { - copyDir("list1", registryPath); - Files.delete(registryPath.resolve(SystemUtils.fileName("org.graalvm.fastr.filelist"))); - - ComponentInfo info = loadLastComponent("fastr"); - storage.loadComponentFiles(info); - List paths = info.getPaths(); - assertTrue(paths.isEmpty()); - } - - /** - * Test of loadComponentMetadata method, of class RegistryStorage. - */ - @Test - public void testLoadMissingComponentMetadata() throws Exception { - copyDir("list1", registryPath); - assertNull(loadLastComponent("rrr")); - } - - @Test - public void testLoadReplacedFiles() throws Exception { - try (InputStream is = getClass().getResourceAsStream("replaced-files.properties")) { - Files.copy(is, registryPath.resolve(SystemUtils.fileName("replaced-files.properties"))); - } - Map> replaced = storage.readReplacedFiles(); - assertEquals(new HashSet<>(Arrays.asList("fastr", "ruby")), new HashSet<>(replaced.get("shared/lib/jline.jar"))); - assertEquals(new HashSet<>(Arrays.asList("ruby", "sulong")), new HashSet<>(replaced.get("share/other/whatever.jar"))); - } - - @Test - public void testLoadReplacedFilesMissing() throws Exception { - Map> replaced = storage.readReplacedFiles(); - assertTrue(replaced.isEmpty()); - } - - /** - * Test of updateReplacedFiles method, of class RegistryStorage. - */ - @Test - public void testUpdateReplacedFiles() throws Exception { - Map> paths = new HashMap<>(); - paths.put("whatever/lib.jar", Arrays.asList("fastr", "sulong")); - storage.updateReplacedFiles(paths); - Path regPath = registryPath.resolve(SystemUtils.fileName("replaced-files.properties")); - Path goldenPath = dataFile("golden-replaced-files.properties"); - List lines1 = Files.readAllLines(goldenPath); - List lines2 = Files.readAllLines(regPath).stream().filter((s) -> !s.startsWith("#")).collect(Collectors.toList()); - assertEquals(lines1, lines2); - } - - /** - * Test of updateReplacedFiles method, of class RegistryStorage. - */ - @Test - public void testUpdateReplacedFilesNone() throws Exception { - try (InputStream is = getClass().getResourceAsStream("replaced-files.properties")) { - Files.copy(is, registryPath.resolve(SystemUtils.fileName("replaced-files.properties"))); - } - Map> paths = new HashMap<>(); - storage.updateReplacedFiles(paths); - Path regPath = registryPath.resolve(SystemUtils.fileName("replaced-files.properties")); - assertFalse(Files.exists(regPath)); - } - - /** - * Test of updateReplacedFiles method, of class RegistryStorage. - */ - @Test - public void testUpdateReplacedFilesEmpty() throws Exception { - Map> paths = new HashMap<>(); - // make some existing file - Path goldenPath = dataFile("golden-replaced-files.properties"); - Path regPath = registryPath.resolve(SystemUtils.fileName("replaced-files.properties")); - Files.copy(goldenPath, regPath, StandardCopyOption.REPLACE_EXISTING); - storage.updateReplacedFiles(paths); - - // should be deleted - assertFalse(Files.exists(regPath)); - - storage.updateReplacedFiles(paths); - // should not be created - assertFalse(Files.exists(regPath)); - } - - /** - * Test of deleteComponent method, of class RegistryStorage. - */ - @Test - public void testDeleteComponent() throws Exception { - copyDir("list2", registryPath); - storage.deleteComponent("fastr"); - - Path fastrComp = registryPath.resolve(SystemUtils.fileName("fastr.component")); - Path fastrList = registryPath.resolve(SystemUtils.fileName("fastr.filelist")); - - assertFalse(Files.exists(fastrComp)); - assertFalse(Files.exists(fastrList)); - - storage.deleteComponent("sulong"); - Path sulongComp = registryPath.resolve(SystemUtils.fileName("sulong.component")); - assertFalse(Files.exists(sulongComp)); - - storage.deleteComponent("leftover"); - Path leftoverList = registryPath.resolve(SystemUtils.fileName("leftover.filelist")); - assertFalse(Files.exists(leftoverList)); - } - - /** - * Test of deleteComponent method, of class RegistryStorage. - */ - @Test - public void testDeleteComponentFailure() throws Exception { - if (isWindows()) { - return; - } - - copyDir("list2", registryPath); - Files.setPosixFilePermissions(registryPath, PosixFilePermissions.fromString("r--r--r--")); - - exception.expect(IOException.class); - try { - storage.deleteComponent("fastr"); - } finally { - try { - // revert permissions, so JUnit can erase temp directory - Files.setPosixFilePermissions(registryPath, PosixFilePermissions.fromString("rwxrwxrwx")); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - /** - * Test of metaToProperties method, of class RegistryStorage. - */ - @Test - public void testMetaToProperties() { - ComponentInfo info = new ComponentInfo("x", "y", "2.0"); - info.addRequiredValue("a", "b"); - - Properties props = DirectoryStorage.metaToProperties(info); - assertEquals("x", props.getProperty(BundleConstants.BUNDLE_ID)); - assertEquals("y", props.getProperty(BundleConstants.BUNDLE_NAME)); - assertEquals("2.0", props.getProperty(BundleConstants.BUNDLE_VERSION)); - assertEquals("b", props.getProperty(BundleConstants.BUNDLE_REQUIRED + "-a")); - } - - @Test - public void testSaveComponent() throws Exception { - ComponentInfo info = new ComponentInfo("x", "y", "2.0"); - info.addRequiredValue("a", "b"); - Path p = registryPath.resolve(SystemUtils.fileName("x.component")); - assertFalse(Files.exists(p)); - storage.saveComponent(info); - assertTrue(Files.exists(p)); - List lines = Files.readAllLines(p).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - List golden = Files.readAllLines(dataFile("golden-save-component.properties")).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - golden.sort(String.CASE_INSENSITIVE_ORDER); - lines.sort(String.CASE_INSENSITIVE_ORDER); - - assertEquals(golden, lines); - - } - - @Test - public void testSaveComponentWithCapabilities() throws Exception { - ComponentInfo info = new ComponentInfo("x", "y", "2.0"); - info.provideValue("a", "foo"); - info.provideValue("v", Version.fromString("1.1.1")); - Path p = registryPath.resolve(SystemUtils.fileName("x.component")); - assertFalse(Files.exists(p)); - storage.saveComponent(info); - assertTrue(Files.exists(p)); - List lines = Files.readAllLines(p).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - List golden = Files.readAllLines(dataFile("golden-save-component2.properties")).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - golden.sort(String.CASE_INSENSITIVE_ORDER); - lines.sort(String.CASE_INSENSITIVE_ORDER); - - assertEquals(golden, lines); - - } - - @Test - public void saveComponentOptionalTags() throws Exception { - ComponentInfo info = new ComponentInfo("x", "y", "2.0"); - info.addWorkingDirectories(Arrays.asList( - "jre/languages/test/scrap", - "jre/lib/test/scrapdir")); - - Path p = registryPath.resolve(SystemUtils.fileName("x.component")); - assertFalse(Files.exists(p)); - storage.saveComponent(info); - assertTrue(Files.exists(p)); - - List lines = Files.readAllLines(p).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - List golden = Files.readAllLines(dataFile("golden-save-optional.properties")).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - golden.sort(String.CASE_INSENSITIVE_ORDER); - lines.sort(String.CASE_INSENSITIVE_ORDER); - - assertEquals(golden, lines); - - } - - @Test - public void saveComponentFiles() throws Exception { - ComponentInfo info = new ComponentInfo("x", "y", "2.0"); - info.addPaths(Arrays.asList("SecondPath/file", "FirstPath/directory/")); - - Path p = registryPath.resolve(SystemUtils.fileName("x.filelist")); - assertFalse(Files.exists(p)); - storage.saveComponentFileList(info); - assertTrue(Files.exists(p)); - - List lines = Files.readAllLines(p).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - List golden = Files.readAllLines(dataFile("golden-save-filelist.properties")).stream() - .filter((l) -> !l.startsWith("#")) - .collect(Collectors.toList()); - golden.sort(String.CASE_INSENSITIVE_ORDER); - lines.sort(String.CASE_INSENSITIVE_ORDER); - - assertEquals(golden, lines); - } - - @Test - public void testAcceptLicense() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - enableLicensesForTesting(); - storage.recordLicenseAccepted(info, "cafebabe", "This is a dummy license", null); - Path p = registryPath.resolve(SystemUtils.fromCommonString( - MessageFormat.format(DirectoryStorage.LICENSE_FILE_TEMPLATE, "cafebabe", "org.graalvm.fastr"))); - Path p2 = registryPath.resolve(SystemUtils.fromCommonString("licenses/cafebabe")); - assertTrue(Files.isReadable(p)); - assertEquals(Arrays.asList("This is a dummy license"), Files.readAllLines(p2)); - } - - /** - * URLs contain characters not representable in filesystem, check they are transliterated. - * - * @throws Exception - */ - @Test - public void testAcceptLicenseWithUrlId() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - enableLicensesForTesting(); - storage.recordLicenseAccepted(info, "http://acme.org/license.txt", "This is a dummy license", null); - Path p = registryPath.resolve(SystemUtils.fromCommonString( - MessageFormat.format(DirectoryStorage.LICENSE_FILE_TEMPLATE, "http___acme.org_license.txt", "org.graalvm.fastr"))); - Path p2 = registryPath.resolve(SystemUtils.fromCommonString("licenses/http___acme.org_license.txt")); - Path p3 = registryPath.resolve(SystemUtils.fromCommonString("licenses/http___acme.org_license.txt.id")); - assertTrue(Files.isReadable(p)); - assertEquals(Arrays.asList("This is a dummy license"), Files.readAllLines(p2)); - assertTrue(Files.isReadable(p3)); - assertEquals(Arrays.asList("http://acme.org/license.txt"), Files.readAllLines(p3)); - } - - /** - * Acceptance test must use transliteration, too. - * - * @throws Exception - */ - @Test - public void testCheckedAcceptedURLLicense() throws Exception { - String urlString = "http://acme.org/license.txt"; - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - enableLicensesForTesting(); - storage.recordLicenseAccepted(info, urlString, "This is a dummy license", null); - - assertNotNull(storage.licenseAccepted(info, urlString)); - } - - /** - * When listing licenses, Ids cannot be transliterated back, so they are stored\ aside. - * - * @throws Exception - */ - @Test - public void testCheckedAcceptedURLLicenseListed() throws Exception { - String urlString = "http://acme.org/license.txt"; - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - enableLicensesForTesting(); - storage.recordLicenseAccepted(info, urlString, "This is a dummy license", null); - - Map> lics = storage.findAcceptedLicenses(); - assertNotNull(lics.get(urlString)); - } - - @Test - public void testLicenseAccepted1() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - ComponentInfo info2 = loadLastComponent("ruby"); - - Path p = registryPath.resolve(SystemUtils.fromCommonString( - MessageFormat.format(DirectoryStorage.LICENSE_FILE_TEMPLATE, "cafebabe", "org.graalvm.fastr"))); - Files.createDirectories(p.getParent()); - Files.write(p, Arrays.asList("ahoj")); - - enableLicensesForTesting(); - assertNotNull(storage.licenseAccepted(info, "cafebabe")); - assertNotNull(storage.licenseAccepted(info2, "cafebabe")); - } - - /** - * Checks that license management is disabled, that is no license is reported as accepted even - * if the data (by some miracle) exist. - */ - @Test - public void testLicensesDecativated() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - - Path p = registryPath.resolve(SystemUtils.fromCommonString("licenses/cafebabe.accepted/org.graalvm.fastr")); - Files.createDirectories(p.getParent()); - Files.write(p, Arrays.asList("ahoj")); - assertNull(storage.licenseAccepted(info, "cafebabe")); - } - - /** - * Checks that no license is recorded, as the feature must be disabled. - */ - @Test - public void testLicensesNotRecorded() throws Exception { - copyDir("list1", registryPath); - ComponentInfo info = loadLastComponent("fastr"); - - Path p = registryPath.resolve(SystemUtils.fromCommonString("licenses/cafebabe.accepted/org.graalvm.fastr")); - Files.createDirectories(p.getParent()); - Files.write(p, Arrays.asList("ahoj")); - - assertNull(storage.licenseAccepted(info, "cafebabe")); - } - - /** - * Checks that graalvm.core is present in the list. - */ - @Test - public void testCoreComponentPresent() throws Exception { - copyDir("list1", registryPath); - assertTrue("Must contain graalvm core", storage.listComponentIDs().contains(BundleConstants.GRAAL_COMPONENT_ID)); - } - - @Test - public void testKnowsNativeComponent() throws Exception { - copyDir("list3", registryPath); - Collection ids = storage.listComponentIDs(); - assertTrue(ids.contains("fastr")); - assertTrue(ids.contains("ruby")); - Set cis = storage.loadComponentMetadata("ruby"); - assertEquals(1, cis.size()); - ComponentInfo ci = cis.iterator().next(); - assertTrue(ci.isNativeComponent()); - } - - @Test - public void testRefuseInstallationForROPosix() throws Exception { - PosixFileAttributeView posix = registryPath.getFileSystem().provider().getFileAttributeView(registryPath, PosixFileAttributeView.class); - Assume.assumeTrue("Not a POSIX system", posix != null); - try { - // simulate an unreadable directory: - posix.setPermissions(PosixFilePermissions.fromString("r-xr-xr-x")); - - exception.expect(FailedOperationException.class); - exception.expectMessage("ERROR_MustBecomeUser"); - storage.saveComponent(null); - } finally { - posix.setPermissions(PosixFilePermissions.fromString("rwxrwxr-x")); - } - } - - @Test - public void testGraalVMCoreComponentNative() throws Exception { - // fake a release file - Files.copy(dataFile("release_simple.properties"), graalVMPath.resolve("release")); - Path meta = registryPath.resolve(BundleConstants.GRAAL_COMPONENT_ID + ".meta"); - // create the component storage, tag core component with .meta file - Files.createFile(meta); - - Set infos = storage.loadComponentMetadata(BundleConstants.GRAAL_COMPONENT_ID); - assertEquals(1, infos.size()); - ComponentInfo ci = infos.iterator().next(); - assertTrue(ci.isNativeComponent()); - } - - @Test - public void testGraalVMCoreComponentRegular() throws Exception { - Files.copy(dataFile("release_simple.properties"), graalVMPath.resolve("release")); - - Set infos = storage.loadComponentMetadata(BundleConstants.GRAAL_COMPONENT_ID); - assertEquals(1, infos.size()); - ComponentInfo ci = infos.iterator().next(); - assertFalse(ci.isNativeComponent()); - } - - /** - * Checks that the 'stability level' is saved to the registry. - */ - @Test - public void testStabilityLevelSaved() throws Exception { - ComponentInfo info = new ComponentInfo("x", "y", "2.0"); - info.setStability(StabilityLevel.Experimental_Earlyadopter); - storage.saveComponent(info); - - Properties props = new Properties(); - try (InputStream is = Files.newInputStream(registryPath.resolve("x.component"))) { - props.load(is); - } - // check the -Level was saved, and corresponds to the enum's text - String p = props.getProperty(BundleConstants.BUNDLE_STABILITY2); - assertEquals(StabilityLevel.Experimental_Earlyadopter.toString(), p); - assertNull(props.getProperty(BundleConstants.BUNDLE_STABILITY)); - - // recreate the storage: - storage = new DirectoryStorage(this, registryPath, graalVMPath); - // the default assumed by most test data. - storage.setJavaVersion("8"); - - Set loaded = storage.loadComponentMetadata("x"); - assertEquals(1, loaded.size()); - ComponentInfo compare = loaded.iterator().next(); - - assertEquals(info.getStability(), compare.getStability()); - } - - /** - * Checks that stability level is loaded from the old property as well. Not strictly necessary, - * but may improve compatibility for older bundled stuff. - */ - @Test - public void testStabilityLevelLoadsOld() throws Exception { - Files.write(registryPath.resolve("x.component"), Arrays.asList( - "Bundle-Name=y", - "Bundle-Symbolic-Name=x", - "Bundle-Version=2.0", - "x-GraalVM-Stability=experimental-earlyadopter")); - Set loaded = storage.loadComponentMetadata("x"); - assertEquals(1, loaded.size()); - ComponentInfo compare = loaded.iterator().next(); - assertEquals(StabilityLevel.Experimental_Earlyadopter, compare.getStability()); - } - - /** - * Checks that the hardcoded core component declares stability level. - */ - @Test - public void testDefaultCoreHasStability() throws Exception { - Files.copy(dataFile("release_simple.properties"), graalVMPath.resolve("release")); - copyDir("emptylist", registryPath); - Set loaded = storage.loadComponentMetadata(BundleConstants.GRAAL_COMPONENT_ID); - assertEquals(1, loaded.size()); - ComponentInfo ci = loaded.iterator().next(); - assertNotNull(ci); - assertEquals(StabilityLevel.Supported, ci.getStability()); - assertFalse(ci.isNativeComponent()); - assertEquals(DistributionType.BUNDLED, ci.getDistributionType()); - } - - /** - * Checks that the core component registration is loaded, if present. - */ - @Test - public void testExplicitCoreMetadata() throws Exception { - Files.copy(dataFile("release_simple.properties"), graalVMPath.resolve("release")); - Files.copy(dataFile("graalvmcore.properties"), registryPath.resolve(BundleConstants.GRAAL_COMPONENT_ID + ".component")); - Set loaded = storage.loadComponentMetadata(BundleConstants.GRAAL_COMPONENT_ID); - assertEquals(1, loaded.size()); - ComponentInfo ci = loaded.iterator().next(); - assertNotNull(ci); - assertEquals(StabilityLevel.Experimental, ci.getStability()); - assertFalse(ci.isNativeComponent()); - assertEquals(DistributionType.BUNDLED, ci.getDistributionType()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/HeaderParserTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/HeaderParserTest.java deleted file mode 100644 index c8121328a305..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/HeaderParserTest.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import org.graalvm.component.installer.MetadataException; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.Version; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class HeaderParserTest extends TestBase { - private HeaderParser v(String content) { - return new HeaderParser(BundleConstants.BUNDLE_VERSION, content, withBundle(HeaderParser.class)); - } - - private HeaderParser r(String content) { - return new HeaderParser(BundleConstants.BUNDLE_REQUIRED, content, withBundle(HeaderParser.class)); - } - - private HeaderParser c(String content) { - return new HeaderParser(BundleConstants.BUNDLE_PROVIDED, content, withBundle(HeaderParser.class)); - } - - private HeaderParser d(String content) { - return new HeaderParser(BundleConstants.BUNDLE_DEPENDENCY, content, withBundle(HeaderParser.class)); - } - - private static void assertHeader(MetadataException ex) { - assertEquals(BundleConstants.BUNDLE_VERSION, ex.getOffendingHeader()); - } - - @Test - public void testVersionComponents() { - assertEquals("1", v("1").version()); - assertEquals("1.1", v("1.1").version()); - assertEquals("1.2.1", v("1.2.1").version()); - assertEquals("1.2.1.whatever", v("1.2.1.whatever").version()); - } - - @Test - public void testNonDigitsInVersion() { - try { - v("1a").version(); - fail("Must fail on incorrect major"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v("aa").version(); - fail("Must fail on incorrect major"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v("1.1a").version(); - fail("Must fail on incorrect minor"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v("1.2.1a").version(); - fail("Must fail on incorrect micro"); - } catch (MetadataException ex) { - assertHeader(ex); - } - // relaxed check, this should succeed - v("0.33-dev").version(); - } - - @Test - public void testEmptyVersionComponent() { - try { - v("").version(); - fail("Must fail on empty version"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v(".1").version(); - fail("Must fail on empty major"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v("1..1").version(); - fail("Must fail on empty micro"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v("1.1..").version(); - fail("Must fail on empty micro"); - } catch (MetadataException ex) { - assertHeader(ex); - } - try { - v("1.1.2.").version(); - fail("Must fail on empty qualifier"); - } catch (MetadataException ex) { - assertHeader(ex); - } - } - - @Test(expected = MetadataException.class) - public void testGarbageAfterVersion() { - v("aa 1").version(); - } - - @Test(expected = MetadataException.class) - public void testGarbageBeforeVersion() { - v("1 aa").version(); - } - - @Test - public void testFoo() { - try { - r("org.graalvm; filter := \"()\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - } - - @Test - public void testBadCapabilitySyntax() { - try { - r("foobar").parseRequiredCapabilities(); - fail("Should fail on unkown capability"); - } catch (MetadataException ex) { - assertEquals(BundleConstants.BUNDLE_REQUIRED, ex.getOffendingHeader()); - } - try { - r("foobar = aaa").parseRequiredCapabilities(); - fail("Should fail on invalid syntax"); - } catch (MetadataException ex) { - // expected - } - - try { - r("org.graalvm;").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_MissingVersionFilter", ex.getMessage()); - } - try { - r("org.graalvm; unknown = aaa").parseRequiredCapabilities(); - fail("Should fail on unknown parameter"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedParameters", ex.getMessage()); - } - try { - r("org.graalvm; unknown := aaa").parseRequiredCapabilities(); - fail("Should fail on unknown directive"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedDirectives", ex.getMessage()); - } - try { - r("org.graalvm; filter := aaa").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - try { - r("org.graalvm; filter := ()").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidParameterSyntax", ex.getMessage()); - } - } - - @Test - public void testBadProvideCapabilitySyntax() { - try { - r("org.graalvm; = \"CE\"; native_version:Version=\"19.3").parseProvidedCapabilities(); - fail("Should fail on invalid capability"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidCapabilityName", ex.getMessage()); - } - try { - r("org.graalvm; edition := \"CE\"").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidCapabilitySyntax", ex.getMessage()); - } - try { - r("org.graalvm; edition :;").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidCapabilitySyntax", ex.getMessage()); - } - try { - r("org.graalvm; edition : #=\"2\";").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidCapabilitySyntax", ex.getMessage()); - } - try { - r("org.graalvm; edition:Unknown=\"2\";").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedCapabilityType", ex.getMessage()); - } - try { - r("org.graalvm; edition").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidCapabilitySyntax", ex.getMessage()); - } - } - - @Test - public void testReadCapabilities() { - Map caps = r("org.graalvm; edition = \"CE\"; native_version:Version=\"19.3\"").parseProvidedCapabilities(); - assertEquals(2, caps.size()); - assertEquals("CE", caps.get("edition")); - assertNotNull(caps.get("native_version")); - Version v = (Version) caps.get("native_version"); - assertEquals(Version.fromString("19.3"), v); - } - - @Test - public void testBadCapabilityUnsupportedType() { - try { - r("org.graalvm; edition:long=\"2\";").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedCapabilityType", ex.getMessage()); - } - try { - r("org.graalvm; edition:double=\"2\";").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedCapabilityType", ex.getMessage()); - } - try { - r("org.graalvm; edition:list=\"2\";").parseProvidedCapabilities(); - fail("Should fail on invalid capability syntax"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedCapabilityType", ex.getMessage()); - } - } - - @Test - public void testBadFilterSyntax() { - try { - r("org.graalvm; filter := \"()\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"(\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - } - - @Test - public void testBadFilterParenthesis() { - try { - r("org.graalvm; filter := \"(graalvm_version=0.32\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"(graalvm_version=0.32)(whatever=111)\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"&(graalvm_version=0.32)(whatever=111)\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - } - - @Test - public void testInvalidFilterAttributeValues() { - try { - r("org.graalvm; filter := \"(&(graalvm_version=0.~32)(whatever=111))\"").parseRequiredCapabilities(); - fail("Should fail on invalid filter attribute value"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"(&(graalvm_version=0.>32)(whatever=111))\"").parseRequiredCapabilities(); - fail("Should fail on invalid filter attribute value"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"(&(graalvm_version=0.<32)(whatever=111))\"").parseRequiredCapabilities(); - fail("Should fail on invalid filter attribute value"); - } catch (MetadataException ex) { - assertEquals("ERROR_InvalidFilterSpecification", ex.getMessage()); - } - } - - @Test - public void testInvalidFilterOperations() { - try { - r("org.graalvm; filter := \"(graalvm_version>0.32\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedFilterOperation", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"(graalvm_version<0.32\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedFilterOperation", ex.getMessage()); - } - try { - r("org.graalvm; filter := \"(graalvm_version=0.32*eee\"").parseRequiredCapabilities(); - fail("Should fail on missing filter"); - } catch (MetadataException ex) { - assertEquals("ERROR_UnsupportedFilterOperation", ex.getMessage()); - } - } - - @Rule public ExpectedException exc = ExpectedException.none(); - - @Test - public void testFilterValueEscaping() { - Map attrs = r("org.graalvm; filter := \"(graalvm_version=0\\32)\"").parseRequiredCapabilities(); - assertEquals("0\\32", attrs.get("graalvm_version")); - } - - @Test - @SuppressWarnings("rawtypes") - public void testFilterMutlipleValues() { - Map m = r("org.graalvm; filter := \"(&(graalvm_version=0.32)(whatever=111))\"").parseRequiredCapabilities(); - assertEquals("0.32", m.get("graalvm_version")); - assertEquals("111", m.get("whatever")); - } - - @Test - public void testFilterDuplicateValues() { - exc.expect(MetadataException.class); - exc.expectMessage("ERROR_DuplicateFilterAttribute"); - r("org.graalvm; filter := \"(&(graalvm_version=0.32)(graalvm_version=111))\"").parseRequiredCapabilities(); - } - - @Test - public void testSimpleProvidedCapability() { - Map v = c("org.graalvm; edition=ee; graalvm_version=ff").parseProvidedCapabilities(); - assertEquals("ee", v.get("edition")); - assertEquals("ff", v.get("graalvm_version")); - } - - @Test - public void testSimpleProvidedCapabilityBad1() { - exc.expect(MetadataException.class); - exc.expectMessage("ERROR_InvalidCapabilitySyntax"); - c("org.graalvm; edition; graalvm_version=ff").parseProvidedCapabilities(); - } - - @Test - public void testSimpleDependency() { - assertTrue(d("").parseDependencies().isEmpty()); - Set s = d("org.graalvm.llvm-toolchain").parseDependencies(); - assertEquals(1, s.size()); - assertEquals("org.graalvm.llvm-toolchain", s.iterator().next()); - } - - @Test - public void testMultipleDependencies() { - Set s = d("org.graalvm.llvm-toolchain, org.graalvm.native-image").parseDependencies(); - assertEquals(2, s.size()); - assertTrue(s.contains("org.graalvm.llvm-toolchain")); - assertTrue(s.contains("org.graalvm.native-image")); - } - - @Test - public void testRejectVersionedDependency() { - exc.expect(MetadataException.class); - exc.expectMessage("ERROR_DependencyParametersNotSupported"); - d("org.graalvm.llvm-toolchain; bundle-version=19.3").parseDependencies(); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/NetworkTestBase.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/NetworkTestBase.java deleted file mode 100644 index 750098eda404..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/NetworkTestBase.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import org.graalvm.component.installer.CommandTestBase; -import org.junit.Rule; - -public class NetworkTestBase extends CommandTestBase { - @Rule public ProxyResource proxyResource = new ProxyResource(); - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ProxyResource.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ProxyResource.java deleted file mode 100644 index bba83a489535..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/ProxyResource.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import org.graalvm.component.installer.persist.test.Handler; -import org.junit.rules.ExternalResource; - -public class ProxyResource extends ExternalResource { - - @Override - protected void after() { - Handler.clear(); - - if (proxyHost != null) { - System.setProperty("http.proxyHost", proxyHost); - } else { - System.clearProperty("http.proxyHost"); - } - if (proxyPort != null) { - System.setProperty("http.proxyPort", proxyPort); - } else { - System.clearProperty("http.proxyPort"); - } - super.after(); // To change body of generated methods, choose Tools | Templates. - } - - @Override - protected void before() throws Throwable { - super.before(); - final String key = "java.protocol.handler.pkgs"; - - String newValue = HANDLER_PACKAGE; - if (System.getProperty(key) != null) { - final String previousValue = System.getProperty(key); - if (!previousValue.contains(newValue)) { - newValue += "|" + previousValue; - } - } - System.setProperty(key, newValue); - - proxyHost = System.getProperty("http.proxyHost"); - proxyPort = System.getProperty("http.proxyPort"); - } - - private static final String HANDLER_PACKAGE = "org.graalvm.component.installer.persist"; - - private String proxyHost; - private String proxyPort; -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/broken1.zip b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/broken1.zip deleted file mode 100644 index db5db8cce3065f849644fb348ec46147247e24ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5081 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenChainedSymlinks.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenChainedSymlinks.properties deleted file mode 100644 index 4ba729d59c63..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenChainedSymlinks.properties +++ /dev/null @@ -1 +0,0 @@ -bin/ruby=jre/bin/rubylauncherx diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenPermissions.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenPermissions.properties deleted file mode 100644 index 02d62cad78f9..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenPermissions.properties +++ /dev/null @@ -1 +0,0 @@ -Path/To/File=eee \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenSymlinks.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenSymlinks.properties deleted file mode 100644 index 865eb3e16b80..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/brokenSymlinks.properties +++ /dev/null @@ -1,5 +0,0 @@ -bin/ruby=../jre/bin/rubylauncher -jre/bin/rubylauncher=rubylauncher2 -jre/bin/rubylauncher2=eeeee - - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/chainedSymlinks.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/chainedSymlinks.properties deleted file mode 100644 index 0a12a265c866..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/chainedSymlinks.properties +++ /dev/null @@ -1,4 +0,0 @@ -bin/ruby=../jre/bin/rubylauncher -jre/bin/rubylauncher=../../jre/bin/rubylauncher2 -jre/bin/rubylauncher2=ruby - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/circularSymlinks.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/circularSymlinks.properties deleted file mode 100644 index 4338ea0c957f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/circularSymlinks.properties +++ /dev/null @@ -1,3 +0,0 @@ -bin/ruby=../jre/bin/rubylauncher -jre/bin/rubylauncher=rubylauncher2 -jre/bin/rubylauncher2=../../bin/ruby diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/catalog b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/catalog deleted file mode 100644 index 588be2b81a80..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/catalog +++ /dev/null @@ -1,12 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/core1.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/core1.component deleted file mode 100644 index 8db465aa77cd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/core1.component +++ /dev/null @@ -1,8 +0,0 @@ -Bundle-Name: GraalVM Core -Bundle-Symbolic-Name: org.graalvm -Bundle-Version: 1.0.1.0 -Bundle-ProvideCapability-edition="ee -Bundle-ProvideCapability-release="candidate -Bundle-ProvideCapability-version=V1.0.1.0 - - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeBundled.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeBundled.properties deleted file mode 100644 index c41f26b2c72d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeBundled.properties +++ /dev/null @@ -1,5 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Name: Truffle Ruby -Bundle-Version: 1.0 -Bundle-RequireCapability: org.graalvm; filter := "(&(graalvm_version=0.32)(os_arch=amd64))" -x-GraalVM-Component-Distribution: bundled diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeInvalid.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeInvalid.properties deleted file mode 100644 index 7704d34dd271..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeInvalid.properties +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Name: Truffle Ruby -Bundle-Version: 1.0 -Bundle-RequireCapability: org.graalvm; filter := "(&(graalvm_version=0.32)(os_arch=amd64))" -x-GraalVM-Component-Distribution: bart-simpson - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeMissing.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeMissing.properties deleted file mode 100644 index 705edd4f0d26..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/distributionTypeMissing.properties +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Name: Truffle Ruby -Bundle-Version: 1.0 -Bundle-RequireCapability: org.graalvm; filter := "(&(graalvm_version=0.32)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/fastr.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/fastr.properties deleted file mode 100644 index e26790ebec9d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/fastr.properties +++ /dev/null @@ -1,5 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.r -Bundle-Name: FastR -Bundle-Version: 1.0 -Bundle-RequireCapability: org.graalvm; filter := "(&(graalvm_version=0.32)(os_arch=amd64))" -Require-Bundle: org.graalvm.llvm-toolchain diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/licensetest.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/licensetest.jar deleted file mode 100644 index 83eb12e75044d02f437f3134d537340bea3dfd3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8491 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/llvm-toolchain.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/llvm-toolchain.jar deleted file mode 100644 index 523ae5953e2b9cdf834fc9bd0a60ba369c22f0d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1248 zcmWIWW@h1HVBlb2XwC}uVL$>b3@i*unR)vEPBAb9z*Wul3_(-Hz>rmxs*h0dJqpzv zKA@Q(6*-A{>7|M3sl`ZYzo4lFIs>d0WG}+R_c&DLWF{f0LU$R^S75VJa|=o;!RkbS z{^Vfbj|=uOm@TF*0F(#0jU9-6Je^(rf?bPG`RnV3ojB>^cUIf)DHD>nW86@^%?Z@x z>l)&y>*?o)WVV&Bwtv!oA)g6A>0Ll9!XSfC=IiL^>E;?7qUY-t8p6rIY`?T3Ruza# zE4UdLSza(RFo22B-ramn4g#*#`;wdzZzP%j=wNMQi{298?9CRDFex%@y8EH~-c2HA z+bzCN?TI}aWtSctu`KA`#TOiFvO^vVR2p@OPi)>Av(01f^fj%f)0f@kjqARiZ*zH_ z`fb+@;SZ0={W6|(IlLy>(dY1=@`A=$6&LsxN&HC=|5ISM*1K>;AG_cUJNNKyhO=JP z2p#&q2NuFW-^c)c2c+PD7w9{1%mU*fC#Nh|AM7o5pqD@x&07K9j7(e%xRV;(R4@aP z@DRGtBbWt6iyDvzNr(s?*pebblLu4>a>7LD#g;S?dP|^sAqf?s3tLh}=$Zwy5u9)l zy3l}?nM8mI3s+J`=z9TVLK8M};A2b52u-q#C<&X9Nsbv}7iQ9y z0P6y(XJ}}2LDq(n&{-h~9ZPDEV}|$>Gg(1QW?&FtIN+$n1o1s6vqKXZ&`7KajFk=K PB2Xer1Zv6zVg?2PK~Cb| diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/postinstMessage.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/postinstMessage.jar deleted file mode 100644 index 42f43efdda42b211a5f93ead604285af6fddd812..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 452 zcmWIWW@h1HVBlb2SnqblhXDz2GO#fCx`sIFdiuHP|2xIN5CBvv!ob17fuU3cs12^v z*U`_@%{4eg&(|%q$1(emgMi!npQ6p}lVr*^ZmaM(dDN+!eW}F9Eef+!Ch_^Cy?*C5 zyFOk;?8}dPzkh@^oAj)b`F+apYF2jjnS($5%I`(leZR$jb;g=yH$%SHWkkE(xI2~k zmxEtX#kJ4%+YeuMkh}l3e{F|mAOG?E3qtN+CWsq&&%ZR=Zr<|cN$cXpB3~W4`0Lm1 z4YiwV&TfkQwAya{;lpmZ1}wK1{wh*jr+P%j?nFDsF^0(t%z~2MF4;NJb3xA$o`?6k zCjLFz_~7X&NA>yuZ+4DpaqjPr0R1S)2nq#8CN2itL5389$e{uWKt?7J21F1d8w(0T b1keUDu?1*=H!B-R6%!EF0%=2_gBTb9=ys8A diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/requiredKeys.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/requiredKeys.properties deleted file mode 100644 index 9c951db9eb7e..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/requiredKeys.properties +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Symbolic-Name=com.foo.test -Bundle-Name=Booo booo -Bundle-Version=1.0.0 -Bundle-RequireCapability=org.graalvm; filter := "(graalvm_version=0.32)" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/ruby.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/ruby.jar deleted file mode 100644 index c99f57599aab6699b00915e400a0fc4775aa0ec3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180618 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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%0DC@I+r}s!PmtJ?v={O@kPiR> zQsXU5=;q=ffCxt>99JmOc1kv!axebV4ci^?aF!FX zK;)>^LJ^T!`XWh&tF49k+JHChKahe_yK))h7}^De7WI#x(QKy9s8@mf;T95eW~46~aVKUb?_`pSRe= zHH8P%r_1ktKhqiydB&DpV6X1TD$0V$2g-_C5_T&G%io*ogkpd&_YjHfzrb_hV(8jk z7Boc*ka8K^L*;5LXuQLRpUB#?@-_UdkyV$rYbd-6>JAr(1D}Aiwayh~Jdo=cz}XX% zbIS%kI&G)yet_8hnB>+h8&i)e(q?|HDnKA#L4cFwXPezG!x4BQ$0N`R4&;b$kBuI0 zRiSd+0xZOa8~H%8Gao#@RCP}%e*81mv881pYYU0Dn&9Itc|->jL1ceAQN((n(X3N5 zZ*L)jDOc{MZaOTmwkuKIoaES$AZWUXL=LJn<@h1Q7sLK2T9Fb*X5{W3!Nfk@aF?`G zF1gj=coa_6D)MAVoFNj$&_RF$Q8dHZY)1y~MstkdzLs##94=$AJ#o|aEZbxjnYJ;v zG{2eK-`ut@mO&T`aqtSF`dP}CteaMRlD?1cZe-z}g8m&-Q_2TljY3+5sPo$$jy52s zO*6ip!kYhHi1pi<2>dwJ6C&4x=Am8$)x1W;4fyl~5T+{D_ZZ=NC;Xf1^I`KUC50xB z)yJhDCOt;S3G1N7s~nn1$DyxzO=eKjlV-&z-%>WttT?Tu#+xi`M>EbX0k)CeHx$F%$011hMB#Jp)1oudaDi0<%v;J{t2)(-SWsu_j#eDT)FT92^a8|v7(Jjzk`Ocnj z8{CEh$xfS?feiEgC}AquMN*NVu^X?^&M4)6?STC0Nl1+n}3fo7dXwoy&Y|Br?ny2I7+A4 zuJNI3as2RN!jO=-0$*;Ss2;kf+TMl_SHJ=i9sH{bLKmmkCS?7Vx{LU#CrAI`D|C=tV)Z21df> zv;CFahh>=jV&5<`;XvC+rVC9@eFHlX=kdZ{NgS{yX~rom~I_wMZ9Z2V+B9 z2c!SAuK$-sS~aReEn@%x#HRgA5B`@H`M>Sh#oXBSKb5w%bz_Oi5`1rE=NGziMms_i zRURE0UW~4@U2cgtFISP0#g+GGCaB5Mw-{8SCl4+wYx2G&_biig*RqziN(`ArujKAidqhKCK1ci?+8?)X-%Yl& z)7;c&x1{gGSp%iW4?!L)-XGFX%_Y6-2DmYLaV4yYjNCi|8X1RK9TR6xKQQiddUHh6 zT!-|Pe6p$#{v3W%4|mY@?Gs3g2J&)zpLkvL5(9MS9+*4)LG!NaNu4Mlz_pD?n5R33 z_(IuCo3;G4CVLGyG6u7E#HkebWbC}hu$5qWlVQ?0o@~=E;UbP%nJHoMi$6Rt~U_99ja~VSqC5HK(Zk^#SBaA z))?8tCq}%K)y*1xvim9yxvsQXbF9=nlMBk31o1yiEdEQ+toPJT;J{c9BQ|QE05hj} z9_~n&b$Jprimb|M{yP0lpdLB{iyDbW3W}SKiO8)ONpox->3AD)E%kWm6Q+U*NZeeC zozWvwHhGi@3vog*C+g1$E89QP@j?7syHYFs7cyIVZyWn1l5(uW`3tg_0gIasfX?Xj zT~~8zI!a`cI8h-dA3TzA*WXc9VvOhBZ|S#RD5I|45tYtf67rWXNddP`0g}yqC2>8k zO#5B0yNhp^#tV{+zti;1=A3_i!7l6{vbhg_P1>s--OftfN5WA}^w=#J^*N2tOQ^^v zT7p8ilZ4l7S~-H9J97t=I4jMlv6G&)j~PK|hBc_7k)#XtxyMN4>X38-$E`W~qob(T zW70~;rwQ%td8rqlMJYb{fcuhyi-n)DJBgO|?qDd_6pI_k!P7_fpX)5*W<79F&KQ*r zj#5T{07#M6xLNCD{mF}11%k4WHN3xBkgcua4}q>l5+&#qp2{M7YwI5T{}?49q1a`7 zddmlvu#L2V*@&#JP|;^awd+k)F^2by%lNA!Hq?v{`QZrULAql6!CdIk0jIYvnc3{8 zKv8{Ce_mr;Zfx^b_ez&aPKMFfH6QG|V8`Tk9uk7sh5~jKN`y5sFU<)3^~<5ujL*_v zhtxZyq>WxCJi%jf&Tcd*tGBfqd}4+^SAq2i4?OcQjEr7QAe73MSztm(5k9#LZirMJ zARH?qHwDieXO~p5xhV@#$Z3t-lyf0;(6$Htd;0*^p-S;EEj~U`Aj}n&tc-OPHc4>h zIgMXuPM&J)`)QvBiZWbAa@91fa8`gjKZgfq>7y^m0*Pkv6`EBlho?+YMC=+yFRDdo zv2Y1sG}%BYzvLQH5eDvwyr4t1USck6UCPJ$*UWxMIW+15%U&mQOyzIusLS6J7HGth zUxsKsh5jvDFVH$^&ho$G{=&#;Kh&+&AN_8sL}?VDNG<^<^wwEO;f@4EO-5q&V`?Oh z7(K0*XDu=xZcsuf6b{fvh-x`fNDG{* z5kWpw%{#DIFr)Q!tU;Qd4S8X9hq(h}NFjdQYT%oK3XF(yF#_hU@~d zErF3`4uJ`vl(7&h@C{RFAo0g^V5R0 zt(J&;Dd1Z9lUZxdLBbE05YW?boIn)t-0)tTWe-oF;Uya{77>r69Y3)8D$ z6zniIhn~(Vll{20B77Fb@kI`ju!N-+JdIKsNI{~gB>Z|`TDO2NPa|$PHu7#PR0mbV07*N>bIMPr0IQm)Uw3%0YC_6%xtTozqIb5+>xe51R+|h@C92 zUC|gUPO(f#WAL7MCw$n-}Tn zNRNAilfusETm;RCT5`lsd^RW0??aa6cKvzj7dfbGM@u~~CTA6uHe#!7PW3{~!jTrH zpMD>G%VY*_yB&t%ymkt$FuR=DoV57OiS<`I?X*YfUGBnWrtf4`pw5R+lPteMn?Ij4 zGq%HHBlXt$S>$O{JCqI}_{J{Y3_OH!U#Xnbkh9zW%Kgw#Q35ieg!#ZL(_PMb^u=qxbk-O!2R;YIb)Ws$dOP0e~?hdQJ^`0Fs>A3QX5AXN{w_H1BD`gwVV z@k1$lYpy>ZysbH`p)AlzSo_bXcAV z=|>F?mWJ6jfx=GLB6MKWiMk`sT1+T2_osJ&88R01{ZUt70l8_3{mc(MC-Xn-&s0bF zy(U0I=!?e@AEaiS-d9-|LDSKTsY{QaG6?wG$M6PxUi+>%Lx8ZjQOwHqi0p?LLM*&O z3eR$eYhb3;g0=7Hq3qn#8eYY@$Ky-@?h2=Bf%Z+?+aUDRaS)*mfAX@B4q#v;8pd#G zB{l@BVlte|Y)>u5Duhk|m6UO zbrcqXQ{8`3mGQ>*7c3JOr3N-$%P=b(qb;0va%?T+HOb0apQs%MWOmh{kCxiWM~@GW z=RNKuMRl8UPUNj#B9KE&dF1;V-pg6A1sPLpT)QTa`(cTq-qwh5n$CWb?-=6u_DEk_ z#uw5W1y5l57+1gb;RO@)FqlZv1@Y*mg~h|c$=Bb&tizhpaZPAm`ta{fT!}o)32iaE zmN#0XKql$Facu88>^k?_9>#Wb{G9VW5ABXSFxqS4`iS*xmJ&3?mh5Z(?tGO9k1MNH z=5h5Sit8I|y%RbfbuVRS@3a{=c!TL;OU2QEeYQ#Nr`;hh`L>!C;ugzwC^0EP%q;YG zqjxWFm|qVdFzn8BUeUfrf{8lfnt26%f3j*K0BXl*JJ;rCqdk>lOiI`Yn@3fpNiV$( za{gsoIb~zf{kjMMVGn!)@NJ4VN`~SPIPC@mg>Hnz&ExI7vVii4vg$K{O>ILa)h3Dg z^aICn31DVuGgM8RW16+`7;rO+qbua}AcTJOibnMF<``RGUXzh%V7aq-Mci?z zuZZt0Wuw$Y%A`BWLZIoZh9q8`6{~_66RHsF1Y?hctH|nMB>x-XpnT4qJ0!CD>OOml z{qI_|cI_1r!*po$>!P%M#U_1vg#u*Gde)`pPj7qm{FS{B9w}Lc^iOZP$)j;(FTpW8&>NBNC zKyjixs0t#6wQ79>B)zI?<9KRD27-;WgIi!9b!CT7#CD3k1S&Jn5AcR-|qa79aVzd?K7 zA&kG|%R=SyNucR5YHqf==yPXy!iDmwjFdP2!(JW~nm)BR;{qa20DK3__#+%lp zM_0wQH^~8Yvp1vE;-UwYzO#YSpZ0Bt5l-QpoGYLVv2L<@Kiwk&TlB0wpz^EOXfjBb zkWQ(Sw2}+ywnXafSaggwX(!HxE`Qsi-bR<`oj@QWEM)mm!%|aF!|D_L_{T7xP8i9V zX{_T6U{o&gV*h@`5w6&ErIZ(4FbITlkqvpM#nA{;#{O~can~7X*I^LbJ)J@f9iSfF z?AyG**?6A%J43|Dx*@=;@5W|G`Hb0&MNwjBVJRX<0*g)q7&l<^ zxfx4ziN$)>`e4`+vhnTXWvL5mx@M`t>{71><=0S-R}uDKYtDKsjCL~%J~oIx?#`1Y z_~~=Nz!E&;A1G1{d^w=6$i2K^gO7%B3o-0RdR`DGD5@2O}9pC#QHfbS;XPvi%aeBYyNMGRR z7A7sDnfURO%&%-4L|6t|OJR3)^qP%boUHq==o|DpNnW20J;0_nLem>BdGkJud=qb$HoEC5NNx}?+9vpU9_ph03-TtM&Ek~jPvZnComa<+O z%)1Sqxg`nW(z`55B^Iq%7ZPHd-R;lx1wr^R_xKSCm~s*i^X7_<(I;JRBU0qacAG|~ zcV#20$CPBouVJv_h8np>9p_mm1M?>S=WO7HQ16LuNImN?p4DZ8Vhlur`mA*!)FSu# z&PuY{l4EyubJ6D52xq?)P$cO-mp=!iiL-h_-U>O8jI-i#y(i_AQ2AbP@TIlU&_R4?05vj&C zq9*IrNoi(`)87=7mdu0Rg40`BV}?)3w7RcGSicrij0_pJ1BBo2X+(R43SI-sy;7oh z7)ma;P=qD755ttlJkV1`^d<5LD<5m{!7zE`0xSU(u&uYk3>gq;Z0xIES4daOKjzZz zqVK>GHmM}Qd{>f{sLi(}qK$gVgN)~8-V@Z36SleKk*rImC##037?aeIJSD;KOB-O! zdrrEj9V{PKy-1HV4gZ0@9{USKT@IKCgXaYYoyEIU7%H_IY z?VR>jCt0{BnQ zr_1g+JonHV?_Hv!#n5FW4OveT|6)2P!5s-340b-iTT)}21d2IpJSglkaZ5TdIVg9X zm4NpCxY0G!g3lEHfV4gg7DcR?1{BIH6sa~Qv!QjB2vMYXH;;jj9><)F7UM^5Z(BHL zfC>0dVvXBxaR(mH=Zl7AntXJWYgkJAeXr1MM8qWN{EZCo$2CvQs2dbsGd5^D=z2ZxQ+cv0>@#v7 z1mZC7CF#&YI{Ic^!kt*hCbI+hjP&6ydn0qU;mhnA$bbnQ8MtBBd-AjgQ?^%3cbi?F ze=En-Ys_FH+i=Slc(?2&3fVja*C6)PP`jvx^uD+%z>A_!i!UtDm?y;BRQP*vSblYB z%=Uii8@&YFI(K`&3R!zoVD0*6{Te%cLbuV#g1Ldt_4!#j#-Wht`;JTV2^WPR*`(30 z>&T=qSOcrgHG*ElvFg=U(m6$cKjX1GoWh!V1H8HWI4&S|*z$v62J67T+6>r{&K!*G z=Z_&Ng5R$TJFHkdVr%3b2rkjAXV`2V;d{*H=@*CiL=Vsu>1+MI`bY2D;~U*^(juCq zSsP&KBNK|-*!DsZb{JF&3q(40z8FFVRcJrGwN5vbz{5V!0>IW*r*_jv?G+8~aVoxh z#SE=o!kcQq7^Ley9}N6WuD zId3{^U#l!%1ZHnOd z1eVrg#eUtx+z;Rm7~3xiLmG~*12T+>a+=CE@QN=n=`aQ<^o`TLF9T;8-WV_mPLu+2 z`0et!h%SJYuo4_Sp0;0ZUA)oKir3GDl1lw6(b6Sjpv@XYRelQuX%0ZNjh6|2_UZ=* z3TyKes*o$Y{M?Vl&56~p(2Yvi9Vbj)IAO()Rw$Wj;YvGz}G3##hrmd)B}m z%)76gMJF)&{uAV{MVfVy&~jaXNE-%#SYGUZSvdKR(zS`HzLT?qsWG5-Vrc7NW9ke* zY6mNCSoI4ceSfA!I3|WkKt!@ZR;5DwUN=K*M(Ma=!g*oSTkzY9^LdrzyVkLj+3{rh zR1+0z|6Gz(!kp5%4GSnIM*F27%PVwTtowh|B>j~j2UpxJrp^+9fz z?c1f_({+A2-V1(9C`ijfRIslMi|#aN2fPx=AMHSFi_>hNU^d-t zH>n(7d91+j@4r#)5gGN`F{BhbaUwd`o73am<{ING(|7{$`jGPV>eu`2{3cKmc}F(T z{MB>r;`J--5>es;f$(i=^Rt3d`bdD{OUIbI!MB^81kTs>svN?F46I4jxVzm#szYWo*!)TzzEHlK8c5Asn4|Y%>W-yQR7%a7*5_qL) z&PK-zh?{fkxZe)#LP+G0rI}XWAkgnm?jS7R{lz8tn0*rBF1m{>?-(p|P2y!8?h8B2?uJHH?MN9GBMenVScw7lMHmLX z_3J}|DJ4&YvgjJr*@HaF2WVT@A(#Bp}w^wKj}BCGJ6vmC4Y=W;)n%L zLL2N~=tGy{({lXM3A#rld4=HiFj;%{<55{opfw_`dKKmSH2f-KJh0jEdbC7Ke_Ma4 zpb8J!&3DC|ZG!cgtw=Py*cJ;si-mc_9=6vrd#oNTCiC?zZR~y>L^(alEcBz0D`OW z20}K3AHqr>9d(+Fvwh{QFTpk(Ah z>|##B=j~&So$Z3u)0Qr5aB?r{#kvJCw%2G;E~p>al>EFt$2aT~lTKcj1hLb2n_lM? zCpGheAifMl&Oq58JO<`9q$2m~PBf27E#GC0kn20S&Wmt^FZ{3-JDF~Gc|1!J1-4o^ zc^0&CPgK@K2P_efC~N2Ri@W1p^VWDsR(`tAAlc_Fd$WA^Sq+&-p@thiD)u6}l3AEfq z=$Efi%^dSI_q(m#!}nXmFPTvqcV2_{*f&itn5&VrF!4&p>uS5}p{b!q>BXo=j_3z# z&FvoKQ0l4GW403F#}Tc#$i&oBr&m~_*=w?ngQYG~)mbwsi?XCUz1L3{ckw9s;&7mT z*rCMalQU#x#O3`hl@$edff;8A`L}ZuQ@mDu)(oo7p`x|Peg%u2GZBa04{YC~<6TM> z+;{OvKb8sCtPl9V`Wr@Utj<4SLI%*J{+Hq6Po3S>)cKpkAHmDNyPQ8oeVDOHxo=fe zw{mne(~^^8lQM_^4THMXbg*1rh`;G@PrG66os0BDr|{=-&I-;4kZ|3)h64%AaqRjQKGa`JTa z@@k`FvNY0kUK|9<5E)rpOvrw9F?Ut#`7cGStpHm=WVKoCy!`gepsK|;zr;!W4XtT6Ed zfk};(eZ%&*;;o?f?SAM;$8!yQ#6&pDD{$lT+DXLh5?cxPXJ?tr`(T-D#NWpfc#h0Dhk#Ztx@#vy#HuMw zDzn(zYlYA?v9M+QD|?<0>T4cbT3@tPo&gGuNIVBQN;Ekqn!|=BXVau{rS#XS%^=Dq zQm{x*8$q?JV%$qbhZ>|#it>r$6tdmLiC(a#J?Va*W{JFm`x=KR6n0cb;2rQ)YMi?l z4VPv@rCxJ3Z>lj@vDYVpS}tq=cbN?%I1A`Un)FDJqRL4>P5JmFe~I+YK+*=XR`wcl z>HxUE>H^jLOW__4v3NlTYe##0N-VP-=2cXJBbt&2&N^ESju=p|!EkSrUAgpbGGZVo z6lo|B7xtm~N5fa2@6Kz1h)50X6kd}FrCYolh9$F|&2^Ao{iNjd0;?%y8}KRw;7qOE zKXVD6dp41bHp-86&C`B{OzUo;5xBd!AW(uv>HFxqG1XWgSs)#3!87WOUSd%qmU4VxM z8Uyf|P9NqT;doRKB&;Nj+`I71$e_DWpnfGuF5Um3;y&;&+sLCv3S0U)-er;Qqwq~C zi5@N0UWgI50f)d){(zf{4W8%bL3h6C7}ZMroS+kke8He%yy7wlI^<~YTGDSw)C(u5 zuW9JX#WuBL-YTnOBH@iRt8%)hrOi{WOT4tf^>lQhLFev^nSsDF3^pe>uPj8Q%hyXs z$1U&iNW-6ch?vOa?7{F=x}quIk2i8SU!p zJR^+X%BS0f-7k966P^Jt>(-2dhNptxt!xFr<&B-cq|fLNq+LXXvEVqG!!~5xlc)&@x9U-PxnJnX}&tlj~uaqca#A zn>QZDk;w&c(tfjo{P>%=RU{DZS{4WpkUs!a%kt0no`a!_u?0Xp`Ol$4RnLB%3GMrd z#^#(<@38D!1e)zudDBvPlhs>@B3c5j(NcK&rHfdvZ*GrKf}*8I*#5b5&vX|h`HWS_ z4c$*ZbFSPkWHj^^O$0!@nf)}N;dF$j2TPZvqD*`n;1_Pw=*W*&xR{-T15tBJHpcHt z2u%YY2bYhR*ApF-m(9FsNZ7}_z`ww5rU(ssVhw_=wY6B;h)zyrHB{rWU}fixDrM3I zhYfR8Lc9=xe$a*}2QV{Cry_|lkrX;u7h+U{Hvx*eYqrXgTq_eQcGM&gy4YGpNGD=rT=w^=P8s-M1K)VdCmIT-0Dh-vL1fh{jM@0&aSh9ok=#EIpp?J!){%= zJ&{E-(QurtJErjM6w0aRF>&?}4iUUecvo^5lkkF?oXF8J5m-N_%H{GGZ=o=G`}_p* zc|jhAoTa%*sWGP6P`YVo;$@FBmFCrJWBTebt3AW}f&*E}m<-p6=b*!Ou!?7hGjZRf zjMQ%@>rkC~l1RU#KSjT`&vRros$HgozXTTui+g7&o`rL%_G{W;FiL$Z4bQgedyRy5 ziY`uhgiy&?Slo_RO(Zh*UXnB4TuEli7;P0*yMa3vKpOTf<5;9ow<8XOD3zG(m0%hI z(`mQ?F`bGk`i;xnnsxP?_ZMW%XXkQNOL$7xVwbP6wcFJB-wthXO21^D0ns@K5NjC! z7q;%~VQlfo(3O=UH<;jjW@?ZwMV#YG2qspX4xo}LPIj;` zZe76n#R40IQ6_>tkgv>VEc!fRa?r=%%m?#Koe4hp_{SMs&%P*N(*FO2!e;K zLKa@C(`5eXzpRkG~NbBH0 zthCZ8$y(k5f{|<;O#Xu>wPW@FY%Z20V1g#ehq2rl%m9O{b(mQabhZAfv(U}{A z2XN<8!is7pW!jtV(~Pk;&8l+7BY|`ku3Y z^g;Z{K)D`w;ON0t=!0O`3JZK$%;$mZw>4zFQ?OfPW}A#2 z7Eqjubsi3yh>avxEcNo$el9)!FXTaifZ|uXHbeOT^!%tbX?c zY$y?6Lp=Z7hAdoM9Gvw{?A`2a>YZx8WS};5gS9LnL{uFe%A^2LBls3F?-rl z;l+E>AXWpe0p}1EaxL+8uiJtuFeU7|&)J&!+q7lK+XLoomOool+(4o7`f*&#J#j?* zViTcEkFw>jgO;hRw4-wZyASrlt}0_5d6J7z5P_vEgw3X3;YRObvTmbvREiqicX70< z*;5h0JgH~35t|3((AcS-bVj~DK_x_%eVwZdT*Ax8BZ05+(N^ebCJmc_A%s<1!HEXX zvHJ1RGK~glmr=1h6dUUBSP!pyZytoUAMZh#_Wl)$p>B8SAjxYM?%i3$43k0r3D<=_ zchQu&_#uHkmoK?}Saz?E{AsEqZk}qaYhl9Lg5JAZvmq2MAUfBS8nxbjfzP+=c7WS9 zojP;(l#~zA?_egZf~2j=zJcu18ZRczS619G2{#7&BHi-0#>8VH$0`Bzg=DH zcoGTv>sYmxjz`?TX0aF!Cd~jOG!O=${d+kUMpL_Qwx&*oF7|(HK}8*kYMgOGR!UAu zvRqYCN=}AuihA#VI;K$kd)qU!G%>L;{o5&}k|T!76kxxGfSCUeeBi(OurRa(boIvv zD)w373c+<y4NWg6!eiA2oppCPVF?+SwP741=Aqd_WseqAsKGxZv_ZpR}&SW2$ zH}6n7&h@yTkqoI~h7ewF%{q?qZ9rDVNe<>uBPdvj2N3(@uw~vS>Ejg2oBHl^3yuih zRuV7_H&|~aO4a3F_NgJ&hxlhU(t73;RGD}C8<6&~_zEXn)&1o1Y;gmJBX#%pVCW?j zvR%h#LLpsm3o7gO<`|hb+ave+Z+Dzi40#XjN1G6#KVMB_#%qVT@cl&I|8`T{Q(sk& z1X!^aK>Oz__MZ#)A1lUd-_L}!eNQV84je}#qDiA>bV@20`h%&rS2g`*KFh?$gjeG!s+@h%WNApxc%GN0G1bv$%4CI%*B?J*P^Y%nCe>e$d zywIfl9Rc}m2e+x-G`7be(LJ=ij(2w|3ZrW633I6?{1|1BDNP7WnD{P{vJ{f?o#!88 zO0!Rldp{+X6_c<()hg<#iu#1QFO#F|RDtSULv0^#>({=pqc5k$w49A%|3n&d9oO`w z-~_zju^w?{z`LPP(NT`+wiAUIOTU=h``f0a*BvOe2TZI3U_1PKl|RORZ3i=e+~c38 zWdAX}GS(Y{NZsce-lCzBLsX6o;6i!%O>%-{++3kKlb&uS3ab|p-?6gdKDXnK6fLOv zCu>>n`OQiP-M-*~UOz!6S35fMe@2YtHIh@AS9=4MLM=VpXpu+2UsVo;|Cwa2ILq2? zXF6#Mdni5xx-v{aRFFjbO6vUu!&V8#BcC3TL9-EG9iFWAbbISVD_E_@!ELo3- z5@Zv$!nx~`m|A!2`c$O3hTb&8d2BoV&X;HbhM!V7S+8BcTJzMG)%C@H>i?d~Z3x$u zjb--v+r>f4@a?w`fN=XhKp&Il-#bKmBP(aXwfi4G)}bswGQ;Vtq-e@E4tuWSNW^G-##YS`!^x))-psi0VsZ*q)T_C& z8OdN01w6mGyhCO7u>+&>v`s@Qg}f-%UB(S;$06Y{0H~mxXeDut zUFuLQ92Er&s+cTLS3NiicJv3-qpwSVkHCXag!g0Et_d=07n0BX_Ae^aQv$vnYttfS zO!{!$TGb%zY49^^+A8&3@;c8^$Y^WW87|fK58!ztW8nz48%1frfkJklQq(%%PG-=2 zI)MkCoKI^I-d*~__~P+hY9k%(`~-jdJU8&&m)>lb^3kxoi)#sisKW%~XFy~_xnvQ| zR{n|nSRx**|JNSzfJ3dzJtcOW+1lVW&cj6+Ix=~?JYB}p&hh#zQBBFh?VkE0klz+p zXA%ywhd%-)y^k1u<%{A z5DgXA_Xs~fQ=VEB9u7hC*g?~ENz?W3(2M(ujFsy<3u}9DV#9ATv?Z;W5*rEm#yR*8 z^;?4`NS#WhoHR%9sPSrR%tw1Rep5vuI0wI}C6fV1YM>kTAoyvD>krbkNE9-$mIJm~jlN(36aO>C2TZD`9-3YRwtY`_r~e=L`Sk;24^W%~33C z3%Lf5)MMe4@(0F*T3N(6Mq>*MH|+U}dOu&ZD|3}hX22b5J>!kKJI7t4c1p-3P@Qy2 zGG0M`yKJP#6obF@n&iXV7D!Cs923~mW3lqmBA0xAUNBa{_S`dpr=hZuv!IF|^4@Lk zhd-~SRVpFw=}@*=30&w`{`F0sV!9FMn-5g}H1ao{k&>mUh?uK>#A*b@YAgZDo?r&? zAIht+2HwmccYE)ZoHt|*=x_oVDbRxqFVZbsH8}A4f-q?jeuBofm=D~RXoSB6PLNOB zmy+*JCsOBHFb=ZNoZBpr9`{z^9=aKtFrULOogI26T$6t*?HcF-PM4ed%51AaS8Vx@EyQCa24PD z$y5hybrh4uW8dIp)Z*FYVMTa+g@a&t@KbN&M=SW?S@l3`Ixxo(JqBC4d+Sz75-w+P zV`OPMf%gPG@j6RA>)^KLd!wV61bedCk5Mk2D=A|6n!OQtk~h>gY%|XAG*Phs|<7APgDKrM$(D0W{&Q1!OHMwLe<< zjd(ZHq6&yP}hw`8qDH_CP7Bw|r zNvj9_Ik={>BhFJg^eLhZj4!BN5qLaW3QA~>4)^tRTvW`Jmtt^Vq~&w=)P z%Xf%&7E9VD!Pc#PASv67daOuBm|}#3S1Kgg6uWUXfp!cpaki&RK>*5R7F&-~gdv5mYob60&O%h#gxT)jl(2h$UgnK9&$YTz^IF&^F<{OLF1f)vPe2XOeVU`-Yn{=Vn2~jpkVoF z``sYu63KVBfEwvK;sy6%-=rr*eAQNI;~-4xbU&CMXvn!QG(c0}rnLq{Sjt9ZK`5&% zVzAyZ=0u()@v+#TJf<$gLxTh(_1LI*2e(2cC3nT&N0cs}qi7-Qj)uNv3AaMp2{_?vT4Enu%Q6=BVRG|3pG|*)MuglQvsoucSwh*{u5XGio1TLX zLc}zU)75P2xz<_D@7k}WPQb*l_0Y%KWNN}uL*=ZpKt|Te22*BIetAkjAj0NY;Nwnj zJ-1*Bfldcv>3QmNu-Fh{N8+;{_|@bg=;u6p+8gy(8%)CF)pfmfNHE62p6O}OZAjYz zREE?N+At#Es|!#%VUcRFP<8qRW|MWSYGB5wbSy@FQ>tc~W{Nlg{j&l$&=kqGWw@!j zSQF-!2jGU^xH|ZPsZnnCEZkWI3rNVwCe!1W=aNP|bTSh>=6NfgXQ7os!C`V-(g5op3uy{QYuxe0ql|`0H5KzO9g@@9wCX zfTq+enI&7|AdQh&^JvcJz<30L);4x_(F_koWEdh%S-Ht6Qc2*+D92&J>$}4)&&KPq zVnlih>(%U$(}Mek?M7sU?BH>Wlx!sf41tKX2lJ9^QS*dX^f%=gtL7P-Yb|{ptK@)E zIjsA8w=fH!7Jp)}B?oqP@ebm^LZl9gtZJj)qFS&ZU7qa&Dk!Ma?ld+)^lo~_I zJ_XWN)?Iup4cmf`s3jB^nPz*fP5!S=-y0lHo+QjMxy_z|6QSFbv})^JQeCQe%Zyfa zsJ4GS9oxNwDa=|tz0rH;4K*8lYWn*@_gbfZqt0`cJS+hxkI&!@Xz?1?X6W!& z*yUIJUzC511xbAxn3I3b+JI`vKPUv78QZ!15xq@b5VFr?LW8{F&E1#cc1fgIS6wHc zM<{c23WE$onzPCv0f`+>0FAdTf83ZcpwvT9xdq(*f1W(&AhQx}z3Sbq6oxP^X}Ei* z`G$(7Bnwh){OV5ZZ3?KjY~3vuNAFjL!tw_RhdIJsCO(v?4!~B`i|!4@1d$15f3S^4 zk)BNem0SB**PYxHyn)dPChm0MS2cz0Vo~;G&6KQcW7(ZOH$0mkDXZ|f7ob~}dqfs0 zdX($Y{bw`U0(S;%h){k_D5r3XfX zKN9QK!aIt$J+kW*%dK&=^AwBFvYrxK?--Q|6RW*3@gZIIwH*V&@MJ&e@O8q(@?iRS zjUngGkq&=Bo?#(rSmigcjP3inPjS|zwEaPb-%@+nT|Qm zH|fBWHUBv1=y1D^$?6SuHKo2`?lc?jC$}0%22%^zU0Z2h9*s~n?p#3EO5coVT_%?_1CQzL(N@tlh`mFw8zq z<37*ywkKMEPAB7>+-;u=(ZZ~7s2P1b%H*g#q_lPNhVO6mf+(Y_l^Lcs_7{{7ld==!H42l7Y+sW6EQKE57noJ4 zN~Smz{N)ax)2lOK()TbtJOD=ZwO`{)&hMKma(Y)CWrbipsP}W&^|Rss(lI0e+;V9j=80 zTFs>_49VzbaSL}P_b=p30Ji2sSwG@jf?25va3kr-Or%%8nQE>H^0>fo<|URv5FWZ3!An|ij(`1EMklZmY8ge9$-k`9FbvngPCt=F3nIqNm&<(dR9Q{}pH6-6)8j%h}EwWU+&=%V|2GD5!~%Waa~!deX} z;hVNHxipNkiQJ{6TE5wnN>3Uj*LXS?l~iorsO^l2q8ud{-MrEzgj(VZ!i%O8Gwh^j z`f^fo?@-8ESJf@Vh{B%Zt|vsW^uAOeda9J~l{XJUbl)Vam??h#rMhK>Qu77G#FxU2 zO-nh}yBeQLgp}^q0TnQeFk1z&dh76cE`C36E6pxF?YI!SE87u{js>OXicb!z@r{7@ z>_L;>CLu%el||#a?IJ0mQnep7*YQ)>Cu{hyMDn4GN+p*CDx{2Icdqtt^w=juo z-Mruy1IA9EY*yRyUBay!NEg^jp-b%NK=gdJ=DtjBZ6yr1N2T?&Q0=PR+*4I4YtFxy zq}#tuteQ)I=Tc~=#bT4q%m^3T!zoXNUNPq>KNSelpx;tDO+Ym5`Hve+Eql_H!BAJ@u{^fzKyTDrU4)L$9&SK{~ z)f>RY6$0WP`M-B{rY^<+KNqanVFk*Jbn%D|YKH=K0$J3?5Hv6q-|7&dDwLw$ESNG` zZE~|?&X|fuEgYe@x|Y5+0y1;tbl}dXw%O)oqkb;YS^q8Epg|u)yb=VUvpT1qfS^FV zCqra_vQPVp@TP*+;76N-R4PtFdpK8586tKRX2{9Vf>TIQbV>#L&7Bc`+Kf%f^t&P| z1)&&ts5<4Td93p-^CpD>M-`x zYD*t>%1>qy3V)rw4no0@8$h6#0tAYGFneZZmVfdFbz1=57w-3!zR-(b4!?V932u8| z+DeH>ATTF_vbo4IdWd&v5h#6ZPn`suZ$Tu*`tU%V;ydNc2a*0r8G9|pggDm;Il>sUR zmLP4CKR`glnYns$@bvbt!9Ib^nb9-E9Vnf{!u@m$i?NBq3!oP)YDc5dlYJ^p`sbt3 z-IW`P41Q=^#+B*8@dD%Ij%1lie#>TbfK7X`HIPd-Q|@(qz!6H-XmOANR}18;XB zp=uoU86FeEYjG0~-7K6m-5^T?8ZZx*Xh8Nu7wGsVtRa}hYN5}-N%nSVs1?*nBIEf}AZ7WhZ#%@jD?g!N$U6fWQpx-cbR?hju!O^8$xbNfqEa-YHZ!JFb4s!h zLXG{!s2akmp|69q*%C@tLiva-wM%!7t`8<|w^Px5N%}~R&K#1NS2->y zB33nZpUjvUI@tb|1oC9khRoZg;u)B2%;Zozt<1McRJEG2QH>=d+i%amks@#7shfu< zrqO@IJ7@8AKV0P2%V^&Dooq5pm2@j1DoM+AUgQs#|0+tG(1+pbTE|<7zRF3pZoWLo!S>;_FusD^IpWAM z;uzv%i00a1)O=ZPLyt!8D?}W#p7^ngB~!{)61F?NoNdRr+I$ezEluIMM|5%hCQ@Vb z(soVoOUp-`3pa7Q4?Y~(m)x4=xof?`^;(13_zRQJ3C>a$4)yWxxD5Wemc0(zJOqN= ze0MQU{4nT~sg6N*oAs*Pa%E z?!$fd;*b2kvab?OeieV%zR*MX6t_n|Pu_k&gd)WZxgZ2Es66#vz~vxOlGp!aO`4Z96-Bmgo_wht=-C%i6s6&`G; zX}9qQ;d&?-wIW(@Es4b8@*zV5Cbd(1n{m z1`a7>!rdXgCz1#>pJrX+hx(A9uV{o>omMaN^_XIZeJNO{5kN-I{@AJ(Snjqzl64(V zw(nbudO;lhD={>rYWLJ|pGrH7HroeAB(U#S zj5%f+j3Vg90%LAE^uGsgF_G?wQZGP#MUr0zKZ_G@yllYL026Ln=o={FFeq~@t->n(VNTP64s)NVtPG!T9^CwmKDm$M3o6$FKNl=Fh3;ua>$Wz! zmV5hJ`~t~9IN@c$_h?j3vSZP$FI;VQAtWy4@l!2|c(Wm|S_OM7>d^2w6Gz=)(Sf!_ zKB0~BSy#RhE6dog=N-ftuX7=nrvol9U!O$*lrovwWL2(lwjwiK;jiIr&yMgsV*-5F zMHjzSLKhDnn7Q%*@kXaJXii}qwf9Z`VSG|m@8Slr>HDKu_v2^9W#W<5~ zK?ib|2Qu7n^M>Gj%;poN+AecV{T^;5--Z~7zdiT-AlSZgF?M(B%B%r(NE@W=#XLFS z9GNww$&GYHx2SMk^(At*`wSU5S=b_PUu&aP*M9$8bQ5tG>~-}O=>I@Hy=3?v^hP<` z(H?q`dxkT}SXnNE7b4r#LBpEaF4x8_8Cy-<{#&cf3>O|YXvJ7Tx^~%(rjhiqcdq#C z>)MPxWi4r-Yvb~kj8)D&uZ+I3(&FyR?0kgXpj|R9g>n|@5=u9Of+aP0e~Ym|#?)u8 z1!GRm*_f92^I%g4)o&YD<$LWoD9>PQyXz2Qw3i{uyA{KZ>H0}$k2ho=tPcu}!bq9c zb2XwOVB510hQkc)XzM)v3i_t!;jX;Obdtl^IpEL_m?krBgqYgZ-r<8Q<}7tP))VBj zCXW_YKx4TE_vtS2gfcEY=qsGDu_7uTo`;i!GByYAr5LPOF%%CwoRk909F0>Pl)Q0! z#_SpvfXAT zTbQUNFh)HPB%+DYKOugBSQ2;lD~_#D#z2ht#4~^Yc3o<;#XU2dwteTNNw*jj2uVp&Bm0!UAn&AK6X7CT-UH^&%wkGWV#0nC-vo44LR=@?Yf`0&HFt!J9 zbQ+rfCm>5k25oQ|Ot=vEBznV4OYb|c7Gz!4*@F?^`qo##c<>x(^Iu!cHBmWo!!_7KoYS z@;dV;W^)UY^_C55_N5!5vEK4@OQ@7vlYwUw!Osd$j0AROM^*Z`3&{Yfd-{aN)X)-< z67W!|I#wgc$4K9xfhk8+Rr4c`6x}XQVmAl&qsO%7r%x@ESDN)w5LRaTBFnO~54qwn zgeose*kM0-&6U2*Zr}KU{GHc~$Sp%lUp1z~PWCMJKTc`?eai6<_OiW$shzX44ZX9= zHzVi2WgdA!@OYkp1D`JRKYH%-*RKBcAHXz%)ofKZB;kJN=;!+z+AKtcgF?q)A2ZAf zdW`@}tT)a&mHiXxH^g_N{jo8nXCK~>OZxG4TDDo?2d z=5EvmqDl@V)|~`~<(nFW3s~05NH1J5iU&l_261siWUNC7wscCR$_2yXw31TPXT_x_ zJxCf|+Kn3Bd{Ti1xDzt;bb<*2@{ofb#62@JJvenD4Mn85MAKeIco0SedWdc$cFaV< zXmJTrvU*j@;B|2vlsZ+(V4XJoxP(-Tindw)^@Y>H9EI%tq& z`uO+eRS-!EDj3=c_OM1trXg8l3;M&fV0I_5MT!xg)EOI^MS-eH*+zXP{EAcvD|URHZ>GT1UBorU&d3m*gPA z&4W&OP-g3P3YL6unL*O^&H$bYypI^{)O+EDzI4f)RU>s&xu-}!%+VEDORfF$JfxKX zl9V6pR8rxiD!Bz#Jnmo|$$I0BwzeMlrcJc`8|U`+Uic%$+KP>iS(p4H+2t&?^hEd- z#vdmEKUKy_iiiysV!0V3et3wHu#|QrrS53cvV%Is->xDa<5>R;ovma1kxjUngpPE4 zvjDY06Mup4N0rJrh#LEzS zBrVI_vEvj^kHvQQ^0OL^Q3_+T-zLto0dB1?<^y@$n$ZF?Tq_d;uEe8!np6DWioVt6XBj zozUe8tyQBbj7=fPh5;jZtxEo8gb!%Wf%jQ!bqCr`)#JG>I}Yt_$_tAR=YyZm*4G`n z4oEMvGmou~@~3j62@5U;+RJVnyy!C{M2IG_)Wn1J+=6EKUPq`m)#W6R0b5m#WaO`z zmeN+a`nqh!dq-xKLr5$iH=-Z(O93Nv;H^CD<7cX`J zGUx|}oxbn%zP_0R(*YxVZ#R~AqaCGdmxmmCmI?I=iLZw?cUaw1Z@#`cE&*2q7sm^a z8@m?|@t>_{x!!#8fmeHk*QLx=kmjii8w+DMr=y-;8NS2-hYZ(Y-U zSHFEqSFS_7bMcL4Vc!-hLbty*bX%8qNA&gTTC<+2Wz`f{_+a%_KAM2M480i^CC)v* zE#Q7yv9(jk)r@ttc48sd++R@R<;DW^(SHTQ9>4vKG#aW|Fp30_e-HuMKdF3K8vO@| z9q{gQLROkyd6Z6Fl1^rFQc8AQO6~uFFrxthK|uliq3>UQ8tJ76cuf(2PyPpIJ}X04 z!$0|r`i2vrn)3Zw<6;$2-puCLy!^ZrJ3e*u&vtbag$uSsN_ePhNiL#Zpgfb0?}&oK zsiO4*kO@StGdW!Wyu7ys&j$_n)N<1b!wcukUAekBx{B*-YwP)+s~)CPyg2%Dr&PRr zTm$!5Gg8k^jp)U8G!&L{2B>^%+`-Zw8MISmc!~D+Iw}4ELl6t$Ro2$0I0UICFPv>7OO?AqLBBJ0IgW5#wjCS>BdV6ilt7#F7k9AE8na z-YTmXo)4mytk4EWjsyK<{iJ*K42UC#_xyI35rc>rYl%kA-({`>alN$rZ6_6572CG$if!ArZQDl0wqI(Wd*6L$|G0O*lh$Ty`SY!> zeQVA&R_}d`(T8f9>xX&AO;>QwFlHeo9G|Yq7R&o-HM1FS)1bkC+x^y~t-JqjUBeYq zVa?9^tk0f4nE`HGqgIUcfB@>U4LgOd?C>3fpe}os>l(*Mu+~V*PBq#Ntfy=(Qu#4Q zy$~!d7&H9oMcO5gVeugBD7q+qDyU41$Va86$rWmtuIXw-{no5;f!rpu)bV^P0VUS{ zQ!J_}J(YRRop6~oe~U%WQ$J0By=5grJ%7bP-wh-XoiJ7kU2!nz>4H{i(7h(!8pYvq zaug;0Xu~B|IqiCWzXQv=ps{Eiaw|SCFRZUV3M&*E!aG%W^NLpocyVXxw?Pmo0N5ZsWv~_$p?tIh%XC6^ z4ywFc*Hm?hgEF?afJLX2!Xzo|NHp$&?>+UxRR9n6I9(#Putgp7-L`C-Yc+C<`nWYZ z_H{kXiMx6@x(VdlMo06$iaLqJ0Um+Q6Mzc)L)9dg$b>@?Xbb}lUdhARAt-=Up~R_C z4Y=Os2|oyXda-0K^VF92t%-WxVLoF(dV#n~umV%1e!f7*9MxRt6T(PC_Q~|tMlLHk zo6NenwSF*doM@)8FP4;;JStK30~W$hJ<*(5Aq6*WM4Vi+oKEtw)gyw`w5U&f_1`=_ zm6xbu$1CyIY>|;RTzQcOmOr_Y;kZV0+qexHOqitV{f-gEJcFL+pyf!IxWf}HDegeCqx0uw5w=7n}Gi zru~U+_3fdbSwaSNMB!p@U{K{i2v_GvVVQo zIJrzYmD2Et%vTS{e>HymPt-JWTggiJx@yPQ`Ufi4zhTX<%R`e>NJ)%|HPk{?QqhP_ zER2oFC|5(-z}P-a%gM@6kqwuOk4q>I(~3?|(oD`!(~wJ1C>`#Kk5I{1|Fjt!7h4z` zof`MA_VIHKX(_?FzP8Hbsl2{U<4knB99c03XfQ;aUyH021UH#@0q#x)2+L^J6T^Rq+d2!hIRF}9_iI0 zo)opO9`Qw7*L!4pa)qz9E?g-P&(5WvGjF(lva8_)043Cc0pFg$d6bah@WYrS`pKpQaR9>xeI|W_ z2_kO$5A6(yi5!4QZIKEcT?C;Br1zcEjf;uHhxCX%gegwCk>D6J1Bk|+FpR|B2nLsj zFECr(r{ts%`lEd6wq1TvY4i}P?*$k`RQulMN1f13tH8o=1binD~`o0y5I zq8RrcI;JC&p8ylHCX`#Kg%5JtOy}d%A>Ih`LI6cr($#?Y!bRGHJaE8;_+-CT(Pi6M zo};ht={9D=3cI_$+Bo@s1^eIDF{EJjni@uIcQenR#&>? zLNDZa4IQ~99xwKsuyDR7E_9Rwm-IJuTw=i8y+}_vN%1Yo>W=oXz)~r$~ii{YFQAr%zvV%UNLl zTooZqCpH;uunmDT`wYZfPdD14uYzQW-FcwZn7Vn%giLDOAnKG$G3UstC_Mhaxl{BGVU5&!dQ1gjiYgo|tn+dW4bHkudV`3=?0qnAqKzXc&(3*|Ky#VFH68AB zf})0meF|ti%TsicAX;5H3Pv)2@*xSB zsFy@I$!``7`v3qR{k^K$98Xo>a^J)pqd~b1>U3+2$QFLSQ%n~DUGfNE7I|<-+-Hq; zHSDj2%ambD6i1bfN~Ey@-LC7uv{eKh`)3)vut9irshZZQ(EoM;ywRy`67G|($cNFa zGr=kjGfA2XkO3M!rpPi*4q_DwZF>T23cVmMiG277|5zeNBZvaZEUf*+^~4{HvzG$p zv;5JX=fHx6p(lla%(T8&+FyP+5P1R@AaB2YH5XHoswV29p#@ zpn~@`XlmI*R%5e_(&MK=X>VLaQd#0JHJVomb7{F9bUGe5C3(s1jgR%7K%?0H5ok*? z^}yIEqH>pFoM2;@>ZDOI56%;V1c^A5C6#=6QF9R_L(3NZ+4)g<+|o39&3O4*5K74# zo5YDS5K*Y3T5l~i>v?#4DYtU z0c*%*sdl1-X8~$e<)bSceN}Mi6Y4|)-H^=4-X5u-g+m|B43#A!#Q9I_)Re;8-?ASpKPZ_n4ZR(<<*eCv&-2Fn3%?UAk0!R zv}KsLb(VYm*$^y)Y=PiCu3qH0-6i(FwY0I5+Coc4JqI%Cp5+j< z47*emwZSzkMS93~&fH@lB-HJn7;f$1e#cE2-!MBpAU+}E5qOLZJQbVh&`$|7a0{-~ zd@ES$MZIT=9bgW^)~eW{xwAd_u9ryo0lBuhK=kkw7a3n*F>2U2Ti>R=ZC0GYYh&kuBPhNj!tF&yecdlF#=}ExmR%|&M2);c5bE)BSMKAO(aFqP5hNZ zvl3$&z(RS+4Ni)O?Rc7%0-8Wzl&507IP__ zf>KNktV_6V$tC1oh^_%FTo(ZYKDc>n7!seWQv z?ySvd`sTvPc8TscubhUK6Xe&oILV9^MWk7+tXDc;0a9ElJ%{-QZ@0(~cNE8F%ZrX^ zHyoYl-1Uh<-Le(sl1v!a>A)Rx;SBgv=_^4gb`GQxi!(|Rs$8O!?#nQGCD!?jYH-2I zDb3>}jWT2PoaS9+)5Go}itF8QyYOl`ok4q`(-s_DyZltqDl}Jpcziz1b)l~!&U?E4 z*;DEHZ9ps0qm@fS`S=Ga&E1n*#B#)AoJVLknrEt@DlJY~4#4h{tvbJ)UaKAa$(Xf_&utPV7R`!I;5Mt;PX`_+P;Ha63^1{`O5sR6aPCnpvC)D=7@cVZmC}t6~up zFztM|1Z8~&fTd!A(!K{)419wuL@}L5m%RTD$8`Y!t^edxslK4vKf%af)sz;dR)2)< z1|1!-d59TuoaX|mzZWyw6H*Ng>PxFLZu#Tj&W~~a6;^I zIGpVFI;!bItc>Z_qW3%KnpF`hRJg<*5SLMryxsG3G>FL*o2J0Msyc>W#rJTQP(|_r zdpbSYLUp}Ffh+RMTKLU02!gVr258V%rF_6J>4-KDhBp`KUdV1fC^!iND4k~T>Eu_5 zTpPiBFlfE8Uxsc3tNU`t0`aE=!P!Jq1aEHaybS+a?p5`q463m^Z8F-Iw%EM6PD7_d)gGmMbRBOX-+~Qkvg*=b| zJenF)h059^UL2p$EfT1ku}@KTWv5}sBq88kQb3y(x{eV>2p(PtTSt&|#!6Rj)>XK_ zJw}T4>(L)j7n)~mH5ZUfJJuY#+}7Te(ulIK4On04omRPkb34Y^5lLtps2(VCp_Rhd z(wlbz)b{H$nngTjheN81RRY_fH_9Sv%&6ndwPAk?ENmV~R9HI&=c@i#RjYNZt39$C zgUubScw!|rGvD_cNpF|9hF{I-g=j>gJzb9tByquDQqL_Ht<6R?>Oz@l0y`Jgif+U zd3OYLcy*=(U_Oh)6{p{-BzLL39yu1OVU|_&J}fj;ozQ^V3fuyOGxn0(?|pqo5(DKY z*F7T)B1~hrSspuid~{ESgb}sJo2XQrVH~#oOXw#X zWL4j=yBqWf9AEr7k=F9BbX&e(O@<6`PU#plLlO$L86ec2>a!VN>#NQ ztc&e0%KKjRra`u2nK-e?JnNOaBMSPR%}iY+z?P#4d;HhD8S)L&U<(6FTvDL<`cik$V1+__fHw z4)flD&rfo#TbJ~~39&fCb7o8=q)-W&EDYn&WaDKGJ&~u~*>}M##MN@vgnqH$AsXCK z-LFZ1OIWFMN8py@{H#r%f2*fB#=xga{Ni_AU+W)OeOXzXTN|6&nf@yS^Uta5*wm!V z6xHbbf5>Gi{=Z!I{D0-L$@c%nW&ek*3t)}d{*h4s#J7K-ak_o+(63+iU!^D!wBi$D zR3lUpKV_HZ=4i=gD@I2oXTf*;h&&P0Gob$$+Wbf5_&;d#A361JyjhFP68P!slYw8^ zNA`bsg+G_kwz0Ezan-gobTF|t_{)1XTIx?CGU)OdmG&-|U@aRs|&VYGN#5u039lkDq&PA7d;gexJBbe`@)hbA53Jdtbdfoj)ef~ z&qPjU-5Y+z>MBF=_etAPp1ZyH=F~)A* z<%9Pa4f^=@=f9aXB-HjbrGDMY%dbT4KRDliZHT^wuKibEy2D={L$MoXdvpkam+vUx z@+PBb%*PXcVmXBIXEcSdmUcDqdMM`UCUX1PS@G@fk!LQZz!J0;5{!o)jCiI#s&%{^ z9V=ikWt8iYgIm}828Ix`rD=ow;P9$Tt0tJk(2^1S=2tfRBeNAYyT z+~k5~!~8^S5x<0N84ruL(Zef;-H@I(1QlnA+?;~UgV^L(>vVB{K;3(uVHKR}Lpe-W zlYrQ9Miok@abZ_K=PyRBH|M*5g=DlacAu^cf({GxO8zvmU%~gW@U>I+a$V z{!;p4OtFAV6xs9%(izJPON+BROqJf#RaG*HH`&1p!~1W}1FN6`@y%cR4Druwfc~}5 z)>is|MUEOJ@*mvUydsD2!9+^t_lL3kPqb{&U*rMQd>hzV`pVUV+vL@U+L%Mk`SCTVDa}Zx;~us;I@krG1>YtbD_D_;yl8*RunS4;ef^s)lxwTF6aCj&AcXiw z3hiI#;jd$0=;H8o2oiou+3&KUd`*SciuvJG8tjYXR95>vmQK|OBN-}1>>xh&9DFgJ z%9RAOuWKvOX4!)dIVkL0zRRmho!Zt8$;*MgGiBU_qXlaUO}{mLvWiDRgZ(&t+PP60 z%aebvN&$=1{{uGj&_&vrwojUG1649*CbPlWAaNi1*n}K4u3EBE+S}&$2sRa+W=btn zYUg4}EM{mCgZ}wb$6 zlPE&J<{(@9O=@sh8>+camMpTbp|>YLvI7VN7G9VD294xOl-SJPA9>k5PQ9(+ZbVsG zi`2D&r+VklocZ#|7%g$@1p`rAQ;fk$tD}q&q}&F432#_56IKAqwxmf6-$?FC(I^WO zRO=Sxt7NSXO1ldoGvZc0A#Qi*OoGTF}X8HYRVB z#HsXJQ#|vq7cBzK{I5yT4x^zVvrXoF0i1a6_!drJa1@q-y4@8=u9#OGrh-hE0>`07 z1J*FrRO=FHR&SVSYPXys4hhaWi>u*NLwQ=Wf0A>_nAC=gS>;pq+9HUj zkp5oj2bDN=>PI)is%Ru|Ki!K912;MupoSeX+!_KY?{nT3n95@1nkM%M2djO2r3@J#jK|v%9BX(KFj>b=)n2wUsh+&RD!4v-xq64%y#^~XW+h-b ziBs9rk_RGp%8;gfo2d;IiIn!%d5>Z3#Mkci^@4HEtR{3W8bTF4dV+1HEjM*~a)vge zMFo?GTH+?|*dj!$u9OJB!$y_!V|@^9?(J|Vu17(22$O(Y&&;mfJFw(~3FU}3c;N77 zQq_~+PNH)}V)PmyzI+l6<4W*9;?s@9J|1y9iRIzfOhb1r5D7vAGjI0@r{eM-c8JwC z4$quaebC`{CVHM|ujs$)O8Vx{oKk@+*${+*hGCMEJ?^kY@-x^BlNUXw3iD`CV{Wbe zq6;IVn?Y3QH3c!mn!$lUVfSAts#_|0au4z*Fd~#hKQXDwlzpj z3N&G`BUbH4d(7qcMU#L6oj`_L5oniuc!+UD8?*?N%^GEg12i_nP?<}wqYA9?_7N;P z%-V@BWcqH4zk@C1B+Nc(OWDA?x%LB4LZh)Oj`>+*+YUAShTDgZG<|GQ#`WR+!aj;b3hG|U@fZK8vqVanI2o)3%f5dHM5#f7{h-7Lw zaMsizCUG8i5+O6R0wP6)7z6T-vQ%#Nqb!Q_oUCY6uI@a9b3{=TP$9HrEt&er?OqHT zBG{c0zyjeDuwAN-2-BDX?CA7_lO4*$Wjeor^(j*u3F!L$W553NR2Hj-l=}r0vZSTy zGYB_b&2BhNC)$}XP>a^!Zx{N(B^5t|+X|K%_41U&JigKlJ? zP`6^6UxE{|M8)0M5oUVwGYMoV7oS8KMK4^rv`;&C#-rfz*Q}9~enaZ}Pw5|6a)=4u zawtj)w5j+;Bk2W9&H4kg3i8%`nbNP>)L_mn4>gn7)x*1NZOD4x>s5>phY~fY@=Vkq zGUq_6Ai<}r0oW*GGuca_xqSj+aL%i(; z8gh=vLu(LENjOtrZ=afVd`JMRrIKZQl%9;FrS+d%`FZv6X6AH#@nqn{UON`73r#Ic zbEZVsxgR~3@UA6gjnEFf^@vUPBP-U1T>o2{zP=DjvfBVIC84%s(h?;|YbHq_gbFIZ z6lOqefGwtKF2y*ZQY8JNeUPNVcbcqN?`LP0O{FO7R%Y_`k)c#h6`9~U8HsmkOPekjmF@}9PU@)Ey8U8_)X!r~MPbQ7 zfs-iA^g#&u-hm^b0}UkC*%T0(1n&KPSOd~3RTLMc3WC@HZdGr~+WV@xC?rlq#}!LO zd?nN+-M4%2b%<0{=KXR8ccvj^>SAgR5aexs%vQ{WbScdi&KTVD+soRsS}CyyvS3<_ zUZ7e9`^m(&!Pzg`O#KSn3K|ONCOvdfj^mdpt;&N7@mQ2dW%ycjVTk1!A@h-No(Zp< z^xsu`N}Lr!ZQr-bUy2tG60u|kT{Njae+9uSf8b;CVGVaBA>3Ss5K#YW82=y_IIdfN>^nPIisJq#19Z06kvem!hMm^T zCP}jiyj5~!#$HvLJLV02n3iy2!TuUdo-^mHy=!9@LLDU$^aFfZmgoumSw|I&lqZSB zIFQ3xfveNPMy&NVcn1SBoE%4GO5Yu4&F}P3vsC^R<+t|&i}w2#TN9S?H$121-^*@Z zxB3o>e(AflQjtNcUXt?|n^o7&we8i$dS< zoe^HA=2*p%4z}QT92#-rUJH(6iA1Ji4dM+OgU$e0Lj_b9lhIlY-_93~F(PD%-9qH~ zy^A)Hd$r-uV12~tw4Xk4=Wud1b7pxq?$+kMj7?v;Vp-OUeR145co0cjrag9uL`nYQ zRHp=g;`WTLm= zS-i{5FfJ1GTD<9vulkET(e$F-(mGA^wD?8J*`P$JqIG7$IrQG^uGo=-v8aivK~waa zq6s}_g)y!Y9<4ls99{zIP?T=$ma6H{oZTqt7l}#gzEVGlt;CL%*=ZK!q!iADGF}CB zr;xauDfZKAGllJV{lr8~(E&EI1J8QOrpA28&(A?ew??AGJf1@&f3m77D_Mv=6r(MH zRtl9wz0@~w(9ZEuHoy2v!~_K>OrCzs5R-fvjW^!|;z(nUVsw8LA-w(gU>R&u#63#+ zfU(R=kafkQW)QX|4-w|*$TRCQFh|H^9gD{M>&KOs%klPdk{S0%otOh((+0Tjiq^OY zm-7b`i6K6LS0b@nHzFOZt%=sGi!J?&V)yzX>8yTI!4D}zEbw3T?O3Nzp*cIKuzhuj z^>NcxkgYV26}3}AsmPJ+)feYi_+_a+U8|e(FV%wy$w`!{X|en4JXg2PGAOP!T}w^} zqu3dXK+Gaxu#*)KEG><>2+GY+=51Hrn}thE(OcLms^W`EZp7iqLA_0bD7+MON+ZS~ zycyfMRD==>=rGlv1cKhZILhlGYt!%Gfmg(|`j7Zn-7>t6C>T={)v)N6uKe1=CF{L5 zN4eTnE}mE>oR+k1@J4x77XF+G3HqkLRnUJcls~8{wCAe z8HAmmen}WmVE?GN`7b)7YiFnH`ZsQ?cxnA*ar?g6wVN+qAGqWA>Ze$NwV+6mZGj5Y zulO?oTN}wb5_e^?vHNL@z3mvj-8CpuQQX{pwDgKZL-u-09BWp)+Y9 zcTFc#MOr9VlY>mI9P8#*`yLU5y!d^3|AtdiHt*m>yL%3dMM#AE1ARhTtpe3Zz6oH} zAZAJ`;oypoMh!&4_4`N)fhx8-f}H7uK5U541u!5ka;YH14ZSRJ=$sseL;TK297A%& z2rPrD0-oz_$W~mPBc_I3u{_w;w0lV%Zp2iHAAliJ=`(?;!(aW3D~R;=In zO)kW73%xU(ym_c-Z^uxs1~T?=E~;Xt|KP8N;NnEYCyqsZF+=K*4EWA)9`E*aD&7dM z@Wi?*WnODEx_rap=;~86k;NOgq5~MK;}r5rMyH0>fqrBpz7xTp``aqYpg*j?ukn!vR-xO%!JC)*v*f_lmQK-6Rm`q6hPH?uUt2o?y{`#$BKQz=4_zgm9 zj=KY=exY(n)D=I;0YaSz3KR`$0^R*$>d_AU*ZBnchVig-%*ObD)$c?JH@T{kn`Je9 zQ{kFtO)Qjz+iIvSPP0M%pvE6r7^qqzJs0_C5^CNTDZ*$yQ57n28U;50vJLsFY5gK0 zP%e~`UmWEB{rd-f2LC1p{7s-8r_jgN|5BQ!z8*(`uZ#W@iTA&i1=_#KOS~w@`zeltdrjm+`bR*O8Fi;$j%W6@h#x(!4(&SHk&4KIV$WsMq|%7N?j6DnFO& zGGW_ghpROy^14%+=eA>RK3$k3vADxl=i^P$2dp9Rv}O5R`f? z)D-NH9?+aB(4)^c+z}#o2|z4zy5BMj0|L?{ppmf8qEJs?%W{J22R zy}oIA%~FIi>}6RnQ@YvX+h-H5kUF$+t1(18;HWck^n%2qt^y{R)_(iheq5m>{o2qP zr+YX0)slcQdZX1{qtr___6=0WS|ibL%F_y-qgx(!wlGE}=kAO+txcF%xvb98@S^80;)1{aqjm!c{%|K5gYDL!r*#nY?XA8K&qndK>2rl3}uv{xznU7ysYs zsdZ2e%I4P=Zhi?wg8$JLIy#tIXzN>BSQ!4d?`(v;l=)w>VU>#x1e|38TT-u{zBq)h z-YQP&56FSxvXwKC3IpN_^QL3(%QNNO`hW+53Zuj}; zsEJK_j&l|U(B&_d)p-ajoa6H?(UrU#yQw&!mfGL6VCqqYTK0HX%n}XZ-HLw3Etg7I zQ=^JSQ^o1CA{k|Rqcmq(2gV(W5O>Q$N?h>#ln03Mj;0z;u>e>>ZKSVHH*5MWcyBuO zO}(_YEq`S||43BTF4$DRmrBT3K4!BXRkmVdwH8iv~w1H+4GxW=W4RDyyrJh+A12D{!ZEaFeu*Z zX74j1i>R)ls-#)xPm-U$W?gw*2k@C2OtTNq#-v?~W)@M07DLwmetvS~=W&fe008>F zhRt#R=jX>#*XB!V{F6ujYD)fcz75wW$VTw3u_xzKq4(>xnQ66zo5(=`(G!B3s8G(Y zZc{85{w!g&5n+OF3uOg z9>#K%!7JkpzCj8T6w?z-%$Q_*A*eE8Y|ITIHZ3pi*JzP?0T}lfJxuy#UJ5qF8ciHdNMHZ1;QN zXmjsW;$6!=P=%ESLxR#%G4;k10XDIfD_}-A6&0;l_eLzpy6%{uKXOrW(`IJiXeaeN zynJm&2=hs876){Hy9+=@bJ#?Ik8#|o!ZyQ%G65+W#0(#i&(AFq|pKHQ-iZ6=i z{MGjq##f*ZQSM~uQ4%g#XkxiFEcw)lx5L6>*HZ3u7FgT_@O$!#;(ipz4@TiGI@@@T z5|HhhLgl5VPX+|06!6O1m={kk_fG`qC7hg@(QRGCS*EKj6pi>7JYp~R8`?!8xg!% zR(8IA8JX=0>-c($U|H1j`=u7(u5HfW3X{MRqdbIsgN|my z7^9RtXd&-Yv;5AJO8%P@Mq${H9mfel_@t`0#7fm<4kxG;j_!KQA+GbiPcxxx5ThVE z&}huFK? zJ8NW8(Ez-{PAFWb8>|OX7VPEDj)Jhxcg7=qI9S>@36lLr_GbgPof?oSX#7AREXPlvPe3B z%-cEY5x?Gm!(Zz^12KQS0sjIq|C*Q(7|ksMOb-+E_!g>s0)!;ai@hR54(HeNxMK_D2yT5=v{wFb}peO_$esh?fuQy{=|FmRPyU)^L?SlAOF!S z<1f_sW5m5ob^`0zzra@W;Q`y=^bzKS6`?WNdzgB-A z+<1GGYoD|Y^6Hd{vs7>Ws4cy=#xCK>C}KTp9fB_MkEI4jrSE!y=7%;&bVT$6z?gwj z`s``hP(eEG-7!WCN9{Qf5h&D3Q3n>(Rq;T^lsA%4Q#n5hxH-@aInd)o2Wuf3HBUtJ zBR%OFKhD7YP0b)eb~6!AI>~E8f|V2MDpa_g)Kz`$RQ!R38hi9}eha8=@#;!t<~n&J z(sr7X)T}?zs#7x{t{<}kImcW{FUxTlmZuvjt(5VY9Mo@>NFn#NZE}p(A_wI*quLY~ z(1q^)0>UWm**9y@peb4fzYcF1_pMQ|UQA1p)s_N}Dk9EGpt_!}mRpuazfHW zdC1W+>G$?{@pO&cv&|lpq8`{98%Zno{);XAPr*ppi7$=Q7dCtW|NmKo@s&LM3*yuK z*{nagWW||3eR3X4${Ghr%XzZ4cnKr*p?S?_itPF$6Hg_;u_B0Y5Y+%=s@_|mqGF9C zP1oVSfNa{Dn%LG?RG;!>;!cm#jpoWmJm_;|>e9-pP-G_EjPKCZzenKBe3dWL#5wnw zdu;7-ntN+J2+Y?SjD|mycYITbrY*=5pdi&v(TL;ulSah(N+Xssq;@iYr4hRsQ)-;r zB~WXp(-4*~rC$#5P0X=M`xEQ0=LuZ0072f8ZO_HbOp47&0wQ@^Y1rAAOE;}d4%<6p9aTwhx&2$5_IZzvGlP3y3cJmThDqn$G zU>=lHZx?AH14Pku&IWuv1eSGl1dGJ9;P3vFBT1qiF>+_AA1sVl6-%+H$Z23UKhCA* zY&m+TG4}x9c@Tm0d z(e9|HR>B8WtxOosty6rqA=03l9_L0|A0CiBO>rdhwsJXK zw_t16+B@sdrh`eu9*(WP^6TuqHxN7LJN#|3dlV+Tb|@<1b@rfvb7g*-@H1r8#@C_h ztIxmj^>fn_9jvd&yZW_+{-enI*Q@To#{>P>l#zcgt~wqPT22!sAI{}o{;Rm^LX?I4 zx%i8+uQhB7ag9fhzqT{RjbC9z9rj;(_C$0HnANloNiZxTOWNEfca!uv;JUK})(-kV zHe)a#8H#_m!>ZyoX7-PW?9SUBF|aG{k@Mph3%_s7uqIX$yRslRm~{z5T?Cn@nzZ{a zg~UFo$2QN9Sm_QkW9y6utuQx>3{^n*&1tVdj*-5q;xMm%b&l7-(q*F6v_ugvNmR;`W}D78Jc2{{%v28ROQRd zo##Kl`4*=3f2uM%zU=wF!s(YipRIqFXz|2qj}Kt)x{iv!j(;17(5o&TjBlbei+U=Q z=xA8mS=XiL3AY$F%n#mShRgew!^r%?D|1)pMLq9o1VefaszlzNh~FuK+Z5iKW(bP_ zv`~bgO(qy`L?kZYz*w*+$iHEDZ~{^!2`TMCc2JO7dT=Nb^1$GfpqpDYyE+SvrFaR1 zf<_7adB>m_Dzh2(O^s0m^=V+(&nQj>VI%cZ!gkL<2#dK1ROUs14R_E+48$juQ&5~y zP8wI`pj3V_*$7w)mgtP2892NTi8Kobrj8xL(3;gTW0hW~En2Xrc^jrp3%v0v9z-bV$}O)ovC{9p)<#6X%=$N>xNBSesMZ{f2?s)^$y9GL{dS zwj#Q7Yy6-&QQ11?&~DI-zP@gOwnk5# zHZYEDokFefamUp<*hMvB)aj9~djV^FwZN5b#Sa`(>2%06t~-k}>Y0$W-=8(g%r>Q= zc){ZfKAU?R%hTvqr{JczKre1Kic4#2Pj_jM;wk;O8*pMbI}QqJWgNgFTL-@3Z6%>u z_Q3%Wvgw1{EQY%2yeD6T2DhY|J?_8JE&PPNJEOt+^cwf}31pVT)*9S^{tYWCEtQTJPuwbOB%K5jP7!!0PR1E)e(N9AUI z#_R@`Nc}H{s9tHNg0`v3VsFJEX(Hs%3$_GDqe-I3jL*Bii8bt}a~E_PV4GC@qdvvr z4qo+l=OV7Qg4g6*H!$n1j=a7FPqry^^xK0d9*J*me+x0()KLLz1b_NS+?`FB%z67Yz8 z*2@me2&Lw!xtKmLvSyp4<`ymQLHI@*B#Rs66vWW(2hZRhG$j8vj2Z|KNdXT6>nk=8 zQze@fWC1C`S^+%!oBnDtoNCvj%End>*x(*HB!;IHW41K9Fp9D7|EhXTlL*v$#i)aS zuL1f#$AAEJO*ZV=Q9mI*fQ{aluLOT9Es@Qc(BrEjAgz*SPGZ@`tNW+w^%K#0vOZF9 z>xpo!JWY*jWW3&i#ny{QkC=5C#h_mYG*V3DD5<^EDAFKx>p@4V-qiZymQA&>O;pN$ zG}p4r^aX|Up#EH&xLYBLR@<7^V$^IT35wsC{QeZp0Pq7QK3YJ7#)VT3h2sb3>MsW# zV1XJ|tCAmG;vYlM_hTE9F4pe1XC@RJ0j$7{{OT@T()GHNRRZFju3P5ir+*t)Thg9; z$M+?&-+r0?{ZnCGUWi{%N{GhNz)@w*YMl+~%a0G?s*jkj$aiHd%$F*<#|Xfr=Fdwzz5JXCI^MsoP9vfZ)qLTj_h-E zhH3r_5T_g!oo%p7<@LIo*>PY4Rm2>p)Bn zwo%@<>%585s*tNSCeI@3`uu?DDnDZ%PZ#&mS2{N}bfuA(dsU?jVZ}YxE)M%3HdOuOe^-SRV~E)`FHpR(#=~cB@7j zqAmp8Unv2m>##{d+Ma!tUpFI)-j(S)Ym(?5GZ6FAH@0gmiH90n6dg}Ky^XfEwvtZy zaL=~!*vo&5&I67heY!w0g!r~qp9NqcNiz0Gz=@r~S zM}rg)c>?08VzExx`)o1m@g$o$KW!C(5i-!`vY~p^7Ni=lojYZq^=!yHD->S}&LapbH_ZMS`ZcFl)D$W&puE32dwoqN&7HU4 zM(q-xt!T~bg2{Oq8jHHej=9YGdXg}UeH%EU)69IDuGLzvUkjI{z$hqkswCR_zSIf#M@!bE8gzLnFgJb%erl${t zC^MYn%?$f~f%V!gcp~z)Xi24&Wh&hs2HOa&=m!+%?N5(|03@Eti4T#eg(gwTL;gW3#oeM}@-!9(3|S&eeS z6tUPfDoUB87wwaxE8SH3RuWnQ3N~4~Ms&^cG)VJ)mi8*#4ZACP8HZU?+J)k%1lU!e zFODCpnb}x>L@s&=g58EqIuD~;@%zs`uv-n*Vv}1)P>hhmE$I1^m>T8nkc|^s_|6l> zDM8l)Jq9HBIIOOvc|(9Hs||(*)KwShD-mPyRfLO6rk8Dd-pa&8yLcqPXi4rs+M?E^ z)T0Y;_eRe^C{e-0kmgTZ8!08!>c9xFXJx6U5?{u^YfeekS4ZZzM!dOWbHwJ16M_ms z5UouPkFulv&Y=)_B^yd|mmj*O`UUT)qdjKx9bQYrqel?z&TdQ?@x7Qj#ilN)+f=|r z0FFZz4IL{aMnMm+nEN)E+XPgixN%tp1lZckz8!+9()5foGaxY}gnRvsUVk6s$Ua;r z>k$hLMeukuJ5kw-J;2y>(C)nes-&q)xW1>?+l#XD=lM@|=*=VNHCUZ*J{{x0S`ERs zK>D9UQTT)!GnUeI>X2fE4cx&7N7(thJR7-&#a0t7>fk2lkew6*ko!%Mw(ecNE_JIA zgM~ZzLZ4~rds&PW=`^LB$!h?!`*>B?irR>WA%(FFoI@Q#VrF$ z=X+EQTc^jbr?>E##H9@KeyWggIG%V1gHC0k@PJD)v5$USNSNlQUejj7#n1~V@xG(L zhP5(FG1uw7TBqyLArcj^+YTe@`9)=Jy9ZQHhO+qUhMwr$(F(zcD2tbBLXscL&) z?XR6bFfZnaf#}iW2?04NVT`+h^e#@G_Ai&B)*WoYvmR5&28kr8+>;=A)zE?XGZhGd zdco%qNrM=;W9cmI&fO*Dk+(M$(ZPDk(ZEg)IQ;Ckqg__Ii&kVzHl|!*d7%j<;BQDH zv+I1RhX9xKuOt}GN=zKtcKHgsISjjl|Rj5kf)cVde2 zmRP&){r+9kF5Ga6!Txzr;`~(R{)^F}|F6dXFX!=3dKsd$@lWT6&rU7+ewqtI7CT)C z$y_Fav=SLZF$F9Eghpm_iY19#QL~lgS9fDt)z#brIHc)uHWQl#K$>qiQKPnq_%g!G z?8wbtY*7Qm!kLnsz9E1H@(3mdgE4(QDyAU7fPa%fPX9^@RFx{7T9;(qEJHOe&G|OLaB&j= zy(Q6Hm~`*rDvidaE=_x=^kxhFAmnH_`k5JY=I-t=3Ql5+Z&2o8M=x|mjV6f}f6bPLx< zDopEU0hTnkxj_iD38G^{oGkmcamzoY!1bZAaXHe zf1AmY~RA^$dzINFL zrl-GRWV*T7JZqMYo7vHl&D(X3jzr5P^P^yChTWH+DGO1XYgW!mtBbz_N5GF?0NVYg zo*Be^IpZN87+5uh6%*J2t~NSAxo5%-+Xtz?w`Y=Bgrez@iS8l(`ol$N~ zk-GwB_pfpnCnD53OB;Qu+~!95$yrd%o_7$bhQoPoa9!usNOjW>x}4dDD&{em+JuW{ zH$FEE|CVBlL*bqS)CW@Yq~2i}(g@&=x_+@o40m3;0AYQIp4(uDx4$@7xnNsCO=|;@ zlnF}$zvp|+qeGCTkEo-Dq!EGbNfg{6DK^3o5rS~C_Kj6mf-eCFvwfM(-%gGc&Qk}l z6l8F&wGwvCm|XO$@|!SCh~5K$W#1ubp_Y&PN8 zQ~IlId&j5y93g-qbs*IAj*Ec&atRzFT(6GzOn+T&>?j2<1Ut|Wx^wH!7P9|~U91?6 z3TLn0I9-}0fUnx}1iiNR-(zX%ss&*ACzgKy$YlQoOX^?8mWi$Fzl?qViX;WA4SM8| zolh#b=^!N3r6Rf@elUYzeu>7umH~(Y@@JPS+0+=~QdpaBuUc#}Er=~#>MF0kWMuU7m@)nRiA0^hm3PHzw3h@F zOF&RCGmCyBH%p8Q4rqm(Ir{P(*v&vUNsh52zN-8YFA}&~J$r|#Po^9VmAMi+OaD!- zlyW7s2k^wvpG1Q_L2WIn5H`IiTp6h_={ZP5&llYvTcuRoFAt;6to1Pz4Wm)chq&F; zz`?N{; zF?6}(J?pvK6rP(=#@wQ1-yc!yUThN&C*#qskKOrgRYGSm4BrioGb!&*oYVu_AZPGZ zuK<}Zp<JokaoXjQXQ` z#fA%{2jY4%jEKiK;tq0a7b&FbHgM%cZAh))tqZeCWbWS2o8@Z(HLTQ7DemqMQd}|P zR$E*fnx);{k+g}n$T))w(+%)hUSv?y9!$ju&w=YMq5=rcp2 z9sG!=7C%wK^g%KvTv4Uy}Y9O8%Rexbs>6cOmy=!V!9PAx>f5`f2T zWGaW9nxP(VTJ3c^KUd%;j!%2h)n#=TKM^@Hnrd@gS-r{B>iQY=lz-YPL9oU@h%Z3i zxZDO0xC0c_P(O2N)fH>F3`Xk_S{2o2e90g(3ni%9UvSf6Q(nUi;(#4v)l~`^OGrvJ z;jJW{+^zl#yR=KNmqT`ZvaYIcm^m(b%9F9k0Oz_w<`*+(||-{io`n&vyzb20}Xy~SqbD>)zX&4 zDN9oKJ8s_dQ8XNDVI_<=pV#dN4lt#Ko8m3n77&XNu_a-6yMl>L`TXv#_{8+p{)Ze? z=<~|Mx8>x0P~`E-3LavO=(K9mF(dJj(LhYWfruhZW$vOR2y==3X?9UTwXb#oe);+o zN0B49X=V5%*pwlOo`I6Y)9Hc%8;e1Y4!EMB)gEI_YOyh(bNn!Acm05J>^+bG#zCvw+V)xj&TfM&um0`%+YL)16vB zQ;l**IkLWsh)<+$S^>rf8zAzIn>3eb`z0ujL4uU3%k)RVZb~Tvk!5Zvyv9ZV7%&w8 z)%xF0`Q@;i9XBKW&fEm~EmFwcSk#fYIXNWiP#Dh!)AR~#FqkG_Ovrr(b}AB-U%TcR zk!xdR2W>`)OvvL(!CWy-SCWVqZ5A;WH<-$CexdiPc^!(0m8^7?Vo#T^)Q9CUZ=ao5 z8-Kw>XVf<&nv9ktb>}SC9gAy*fH_?9k8-Ur7}FqMz?%0qi$+3^0x+8MpU#-+wQ-cG z6Lq0cI|*LHN{QvneFD2^fs3~7WM?itsR}t*^1(6h+$0uL+qgQ=+B8;M4GtodXJ^!6Lpw z0e3QqFct~H(GGaFY2}6NE&QVcSG3qk4lTl4!oEKVa3hCV= z?-4XTG6q=lm9k&+&|SCk8sJ`?>Jd()DR5li6GP9qaK9nc(t*&RS4n)c2lrAV(v39? zb8aXFS1;DZYRjL?xL~z;z$3$zJl!g^nr>jc-My>AJT^C7{+##mGu^vDIy^LTH1e{& zgoe3g4YnB9Q$m;6h!{yOq=ZCxTBE{Jz1zZ71SRH>81A&#FI>Fia91|uYVaC45Ooiq z**BOVM3wdNP_;AFt%xzsh0X zpfAg2v&_pe4+hO-eSZwMkXV0oExaPnN3UDqoVXdFO%>5L#@j;H@%vB=m$@vJOl9lJ z*;ymC&$dx2d5@+)y`tQYXkq2uyqAsJa7k!O$P=y$l*1Nj&40<5riP`;5303~vz)tX zp~cVjdD#6ZZ`t7N~GEXm`M5n8kjJPCbx2@S!o8$v-X z+_Yu!NUSSsGR4XdN}4+Cb$vN(o7?ndGa#Dlyn1}Os!hG!zrVB;lQF)FFEmsl`l+ot zmAsy^jdjKqs{pQ)qkWn@R+fqf^!6CW)gxsFvDL}>i-)X8RZKg*k-TN}yz|(W20Rs1 zW_;%kxf~XV`les#Ywn^D>ypZsLVb%akpGxG`6_*>nhm&bYk{NWL1>z#ewUAm6{K_R zk1N>H3v4S7>dgGdJXl%ZTl0*c6*~V}q5n3=cXD>L_%Yo7@5cTR1s$uO#LIi77X4PJ z$dJ}S7b=jqXgD2t5%ZioSbpmK$9T-M6VaKZ^N&xPGWG#f2KRa>#?;N!RqXY!(}(_o zm0$&QW|s8kjwQYY#__2fo}MBwb3|Pz;`cyEa~oAS1U83tyQ+E%sVR}U9@EtAAfrgl zd}k&w1O>V@+QVW-cDr_+Xk%2B{gs!wL)iXnCXOV-dVvl{r{a9wQoRXvM8kUJC zn~KrzWU@P5z?P_6KF+~yEL5&coC5_!?*J2Qe&ZHc_JL(K9R8uSH_{+;`2}>9ao zqsty6_TFdap+~aj#n|wolYh;>mUzWMH)(Q;Rj-+vCi}e0_0%QCJ479M!ss@iwaX@V zoT#SEJ#|dboG+KCQY-A05UnisX69SClY>1R_5lCyNs&(a$aU(^45=pZ|KU#j$E#uC zY+>>b0cRNd(+RWn-t8MDa*JZF-OXbCMdCt&ffNoFERNu8a?%;y0YctsbG~zMi0rnUNFg=JU9>TDZXyOeMgb(znddzgG-Kj0 zeV;g&F6}}1W)&F$yuM=`IJKmPEL3?sCs1xh!r}=0A+K%{NjI57b^;3k8ZrRjJ3^g` zs5=NZwHiUGLf=@Z8MJ^b!QHr42w|=IA>-(is%r|^%3j&7SLF}v|yP>ZLXM76E2Vli|GQ1i7gl>x;$XP_jG z$f*)u3`SK#_9znIvq(_y5n#jx^PUnX(c?QDDMH+71J8jIXmw^x8Huqp?%xwt-wDhWL1{VMB=w2jp$w zh6-FK8cz57p~QVxiqj#8tO2(nQ07)7XZZm-9O22|6yX`;XZ{vYe@N)1ulJnB80)CC zYy>^~V*Aa1VFNmFM~gOjv>(z zUn7I2p{TZmkf78GpfLk>!qp{cXh&p=ut;*giZ^-G}em#y~^_{(l&@rUy1?S=vHgFlc*kkLM~g}IaC zN~}c{QD?k4h;vc=_pzc%Wapd&M{6X8Fw166=5;=DWBh=7Mx?;J%rw*NaQ}vqJ~R~| zF!F<{LTofe)YUy(`uE+NUJw&PA+4{f^P`3j!C>Lp7nUgHPMDmAw*isvrKk<>5Id7- zbp77TT-Gp(Vg@3Gu*i%hdpQWF)yRo#&9+9-htc9M7w`8J_FWc+QUoP<2K2slhWYcg z*JF#H^3a~O0)vl5iw-=OZ4DgooTIbt;Xa)bbkv%~_L#YBHY&h*Rlg^IKb!n*H4 zQ^pW94jT2X2;jCKA}^`7mvjV4KY*KqjK%xVi27k8ytzcVT~i2#ljohBf$tHpOJZzo zlra?C9zXyFV(rLQSq(558X&FRPH~K9)kinNY@0HAOVv5Hx(we+Q z7O*^PZ_jfWksyKeP&qe`u*lu~pyh86iK~p)P`owP95kJ%`7JJDxI;Gj;O={3^V>xO zfK#Ef$bm(63;~bEf;Ary6K08)gA`MC^`QK9UAM+|D7`_!n0YU)?k{2i%ZBxa zwwv36W4=&h=JCG@2K{*?cZzRpQ)<6GbkdBgc~1kQPy2&ZU@hNSxu{*H8gNFY8I`z4el>I3^anxTiFeqa8d4v{UFb9 zaJL>$IKhhhGk-Y?<`73DK{3KK9Fci|>@(dLO*H~>6S1AwOJ59?1Py{n9FSxUEqW!) zP?H;LB8?Cx-Xri6 z^BHEnv5EJ|5unVRv-JKk_h$%pSEVS|;l!Wo610@(;-fng6+IA)+r6#v$TW;BKO%U_ zT<2{Tz2=Bg|42_(;d2)a1~;WxtJ6eJ3>R33gnT59Wm<)H4kxPZfLirqQWWb1)0Drie+lWGM`(u#X{#oM5) z?o(jDX4K~fMdfi_%@eeN6`Csb+s8X2h7l~wRDM>tEOP|IA89kg)lJ%dpCcd({TgBp zouAz3r>l`M828_AP z7=2wq4sfEeM+=w-S1{1xluKWek)Y~My>aJW1ZM9TRi-^&dC68=!J`}=4A9X@ks41R z5|wUY6e||;Mh6z8Te{3A{1?pun^8WOwP@qI87qN^=NBPzpl95mO6q`<{S`{NB5E39 z@%rhN40vI#TVY@qJ!(My2A)d|CwRL#F(X@RJpvZOCkJ5~JFn>B_HJFwdepQHWpH)j z>+hoFRI_so z5z!JTh4;6_i~I=*fo(UI)zG)H)z4+eDM|vffNDltb--T+TR&NavwdIq;GppB{Z_9YD;Kw6Jo$@P z$`kaObB$9BFq7oYN2E!ilrGHo!P$@Xqx!BG8O1x)5rKp1h)PXZ^B+QaOS zZe4vJjb9?+A>#;3SO3Evh=8j_gXsEIY*DuP3c=_Rsa>Kx(L7lcx^;nN|0O2LGK3}O z8gD(g!sdGH1kqn;-yY}TTz&A^6YRb&iRfu(Ri9{{N{-^{&fYu#1^?T9tG$O^HI2L5 zbTXoX5l<8~tP@=YzSJWLFY>uiJs2N{KbAccnIbgGG=V?u?5Y)qvgmmgV!{uXJXs@y zU70dy-`7wj;))=Rb2}oxGmj^AHk@$tdV8gvY(pKKRsh zMyv83a2buf@LI@}7O6;~5Kk#%DFc710F{#@h8ciZTg3NX4PU%~9ra2Tp}|dnPVsr) z2a2s)5Zf2hV5<9o|MBBx{e8s6d`p+7J)*u8Y?Q72(^P2Pt27l)z8wz7Fi{UI_N=T@ zMCpa|+m`T6_Im0oUEm{?HJ1 zBY|XJQ>tJ-cO-AOEVtOU-SNfKR_FH0qrZZ~{UdW(e3wP4gpZTxlYOv-uHGLTTb7^5 zdhGXN`6k<6TPj-MJC*L&WT3xqRkU;}(9M=(Vzu0p>vPkr$0v#3%fHIHw8=bG*DRIq z0D{&D6j~7HD@7o-j1OQkCMsM*DVZEYCxzdlkFm5@pt?G4_ARh8*c8VHeI>neM?ECjHSvwYJ>@gRPj3w*&Bv6YE zgrD{gO@xp7o~KOjNW9xas?j&~!RA;y&|onCVCO;0fh2Cu2OpqppbH=U%HpkM^ZWV! zM%9Ewns4ltKi7QWcZL4rSf`#$RSNShKcN#^0%E{eI2Oqx-xoRRDmrz@z$XaxT@AWI zKf;w#YbPWV;-Klz76)5|O_HO2PkKS0EuVm5#omt+H?+w01nY3O96@oncEe)Lx)9$| zi;K}%7B`Tnn^LSZBX8VGu$x@Kpib{J!HURVKwh^dRL6H*z5`;sLI?z@ zF$L!Ol9v2Kc}^?Y7@?vWx;o5BG#<5QiMO|2s$TMpa`?~ztGP|fJegR3=?KD5%y~3^ zTm(Yasz+<(#Em*0Ye8i+yQKb`am&`PIaZR-2BW?uG(ghbL!5z8tQ3Vh-M^pK?NYi{ z@Ul_mwzwr~DMAfHRGQX=-5sb6nagq1r4E`N0rUP_aJxw+cuP}#&Urqzw8j3_{pFB4 zl?UO^AvG?afv$GSQ!$?8v=mZ1)o>|Q%LD{F#C zDgkk>y~gj{Ad}(7lc)1pbloAyg9q}`S|L*f!enhUa+e8OQ38Yj=r13c!IQVsQ)&;& zpycJ2>a!XFF)Kr&N_Ha;vN86}+x|N7b4O~! z*);CaRIg*hj`Talcj6E7{RI162vf8tkQn(^^U9VBj*)QW~X$BN0I8G z=}eZs5}@wWSN`5^pY(9-$;hS3R#LsBTU8R5II39Ato~)BNgc!U(RiDXqa)LYv~B39 zlT#t0&ss&>j2|FHC2MRpiRINpAnHj3F zUVwKe1CqY>G6_GhS;vR;OHA}$fZu0nhR&}f7}E)nRAojTO(vZJzXK~)&h%n*c{|>5 znvQ79;zS;-6(;=>kJ@ltU5|kjBP3~$wy)=Yb@;VKWApgDr`(Q$!qMRoW@VEd4!3XxwE&ANQKSjjGU z+8)8b*PWa%*E@yHE^Np80^Lzbiq_`6 z+cw~r&XgIg_(T?ftvv52cBU5N7E4ru$jzvHbEx*Hxg#}v9KIHxFNAOZwQCNUBPF=w z|DxO>+F`f+WbKVzuWJ)+>M8&we9F#`4hY-{-2_51H$lMyRry{M@LdVYyR*dEcGQ`Z z>$H?q{&w`ypgC4sO0RWqk5*o8-BnwGP3!5>PyOZy628wj9`XDB56LyL{a44&Xf^=B zAF$1TTm3e&b2Rxsa$bybzvDVRLiYm-mwkRt0qJ3SuDCrp61*{x1!-wCHJy4jb$ep; z-c4sB4iu!!ZuVo66eKj_vnLus-(ZGPFIEX2Nb;=k2b)Q8Cf7`rB0m`OYIdXO) zQon+RH_cIH9~s`Nja^4x?|`nFd>s$@Res^F5GYU|&gepb{7?aTv3?}c(!f!HHZ)?t z6Lf*nD0!-avqUKi0roJUQ#_ZNE^L^Kj@Vc+IfYi%wETYPI04;J+SMuHgbqQ_Yq4(U z`o&bRi)c~GAPi+n0Y^Vc&nO^qGR0|ZS}?tqD}jmXDj@f?>JDlgl{+RMcl1f6nfm5{ z`xlH`<6mO{@j?hxw_*V)Su9CZT}IPi)W77QYFvc+Qpbih?c=3wC|d+pPiZhomO>X| zRu7k$OBmw|5n?&c1AJ!rpfpDp6iA1y6|TYezPxw3=PBM)al8b^Lu{z+ii3%R&pv*Y z{J`_q;6^&@+lbqV1Mt_+@&PY>aS@a&7mbLGp+P^ODKWc2rQpn&F-tmGI+)*WmT%#_Uo<3qc7K#JL5(o#hb8Z>XQh zY^3gnq^l2e`?lX-&-XE8gXR>!wc%Wv;+mbG)s-J^KxdWj!&V2OQWB(BijWjV7f}!v zcs|ok&1<&TQJ264!KB9BZ<}8qL?cL>!~49&^F6X{Zq-O&U=dZ=e?RV8mIQ6{18t~% zrh=>qx@#u~nzBlt`LWL%;&kapK8FqSY?(zu$udd3S|>PeUi}6qNkc+|B#wF@!R^r=Gg>(s=DubD>%~Ams1(Ax;yjdt zh00k;{LBY6Z=mIeexH;IFyVW`_V1c#u7hS{Bex4+MRLP1rME$KdWIr zzSkbOTjM?cMVr?#U3A#aBJee}Z#Vj;ZSoM>W@*KMXVkacX_Ag%tbytjWzf{zb0K`3%okTC1LcQyZ}tk z?cOKnMsNjaWK{jf(4aKEuy}EDy#3AizTyG5yF%3d6p+TOMg&BWlHi;4AU_rqd5Pgf zFt}(mXYI3#aN<9U{R6<{e!;wX-6 z_EB+X-nI~@iE{is)`2*THIfwb16j+H!(9NtlGBzOV+mW74k-pocz}<1aSPR6#teib zx-#}Y7l4sZdXcag5zefTrj71hbNOuN&dl`%gyLW_@_AG@q6$<8{3}_0GjhP@`1nr| zt)a$Fn?}f6F;SRO`tg_RDcmCgivGCY6bDOQ`j!EVfk1{zu}MXa^PXxX4h_}M9qOG2 z(}oIjtspXj`)P^r^X=#2fy%<<=_S-K=y^sB%FOJt0^TFR%J@b_%LTL3SvCF;C90e< z`Vt_&oHCdsP)P`$9(hNAcK|CDAdf@G^-3A57v+ z?qKpYciqIwhH4SnKo(PLY5u7u1w(&U4YgfF~Rsn5&@^*tF`|y{L+EG^0!6t@kesz)zDH?C* zd0elKAI^8jnHSsjT=%`_N^6iq>FN$?-@T6$xE|emuIXqI)kmt8pB)~;*VmIKXYH|u z#Ne8fwb$N904m(980Pr{<`QKA%HHvExKE7K`@xs}qiCEa2p7b$+H&8 zDrX~sfUVkhCayfxG=E$&CdU_KIGLHULVYgbabwnR9wD~sP zB!uue#;o0=_DDMKWxu7N3)d@$vt7JOGgWbOnyg!LZIPr*=ql1z z9bXR)93%Dx{_`Y`RF;!rta}Kg$+|MgpZk&yUEG~2ZjMA92_urzU(Ka3A z<^#8hYvYcy?xJDEnyUh}fmI}N&^xbI0F2}%bx$*{5G!&V=8hp(Lu8;#SeT(T>)j3% z1-!|HX(^H@)jWM4Dhdu75i`LsMYSWcAr-e7#(~??yUJ{>z>;a49JKtdTh`CQ6?3Ry z8`0kEOuT4u0l!A8ifY_@TITh%iiob>NJ*S-?@`T-U|(NrW8>)lSTy+z{Nn3S z?H=vi@pCK|EW9jK>ek4r?D`@TfVYcFvEu9Zx-{ZQqahDtdLCOWQy;{7t?Dr>A4o65 zRIurvJDpJ>$ry1Ehpa`)i02hsPTx3hG)<5(ZLr`;WjcOCZhbN|pIm9PdD(JOVpSe} zY&8~gs+v4*zWmO*=G>fqo)g=rf;XzvWM@+y<9goKM>0+;pbJp8TpG$0^ZWXjpYQ)4 z$nXEl7ybhbklo!lU-4tQUHWNX{BQ5N|NAK`6GvMU>z})>_+OI(elifMj$OtKLPN&U zOOte%EEBbl%{HyELP~iNk7u_qhT37w}-lrFbuAHT7 zkEV=z(x(@fU&pcgGx==!eC@6inO2$HQ>T*Nm|OcVOulAUd6l~1p4yDXf81HO6Q;-M zQhsY&kZLfslX~neCAF^Vchs9$!16Fhs8YbqDo>2u#ZuPIh5aBtT;I@o=l`%OPtago zlndPE0s?eNwBHxOFej&|E)+>y9i=7I0RMX26j&XS8j=)NQ$ONo4<|aaIP-Dg!K_}f z>MvJCk=^J(x1cS;El%mt*6~4<(mPN87&!LDxt~gYXqLpB#b6;lc!NOmga?ip#N`QxVT# z5`aD?8rW^<_o(#1r?;LSoM9oW}RRj=T!7=aq8b*-U z$pth5(?Yn_lixo_wr&v)KR3=u`*ZLNO7D`&C!1J9mTv6DC?<`4^t);*Tp!| zFcr`YZ!M@qbf-1X9F^6jYK2)5u(VmJ&$HPqvsjkkW?cM9YgV=J+-P&>nWITyS4?J& zgsKKP^#dMuAZO`AhKc(qlL%yXaKRNruOlJGQNLNd9+%5)7~aXtjwL6V-!yx+6~=@k z08j-Brv?{UzPHLSV?aWgGOl%|t*6)`cdu3RBK>Llq*RLM8tbLL!;o_S#$NG)=PhxJ2)PQ$`8I zSHjklgM7Zxs@=c6f$kLENk%#7OkTkVouC!Xp`{NRD0ixr%(W2=e<0ce;%(u{yA~aK zC$YaFm{wYEJQ9Ugja8$(e!3HQ7EfcMyM(p(b%-&u1FEmD>y^ZBIYy%2hp-_!MI8X; zm2pgw)vxYfC%eNb+&R!)f{V{ruNvPJtUw>uJjy zow+ctyOUg`1%mah(5xOHZoj7VYTC}`9gE9t@_d=}$CCg4kAX41M1tz*KgQteA2P-N zc=y}b8M|2jlTpQ}8YCf#A$-o%niH4^L`0p8MkNc7pdruS&!`_e7KCmAiiTyln4%VO zKWsdhn!4Gw4-%`nPr&5kxcFz{scczi_;NR%!Y?6lVl zRw`lk<}66uo7;z87-^T@O-f8^=~QtPYjV_NlXMfeqNb(_IvR#1(V*tJpO0B!+k4iq zVO5{n)W;KsJSZ1wYv_jDE0kTpZX8K;zA#<62w=6472}}L*AM~t`^k7*i<2MLjTh@v z9yKA^;tZtVL;6q?JPt6dGOC}nX#o`&h)vC}w|_X(uU@(S5P!z@s;4dS|3;1rWKM={ zB#Di$+ZdC7Y13`ZtYko5M5`mmnkkn>X8~&;ZZPu~NGo_b!v&9fWT8$$ZIr?%MeS^N z_2$F>cDwm8KgB&Bt6@&_E>wv9E#3y@xvrBxh*VJXC1iZCEP#aIW*nG7qgR3VF?@ZM9xehBQj9DV*iA+PsgRxFiy-Q=mBgK@ z3AH^S#VwOb|AG(jN~LHPzzB(;ggZn{s1TQ9ox3$>ffs<}jm*2kbxGDJve~ z#HmkCRa4rP*4K}V*A|OqD^TL}G(mjDdK2jyC`({SoR0i*xyl5RSc5tS%58g;QM+Ov zq0Sm+ekd`#0f`)gSW|2VZ=T{iJz_8EtDA-`__o!@Sh3xSE^@$&4>5ILWhY|09faQ< zvSH)mBe(PeCMF&s>TEnzTY)Clv+>FCM@HQCPPQ=4xOm_3>A_6a3V8}imy}e2WvYV9 zZmmF`4qa}7P-Om1`!#_%R!A`&S2L}ow=YEx)wEAuSV$I7xO`qN$maMo?9=*;&n(OX zLS+t%+YIMOW5Y9%Q4~wI<25b>^@))odEh#2U`v2vd|Q=rU6{6vcZ3$Gu%9f~*DMmX z*aywXD91iYRzYlb>dwW96Rkd*sqmQ~Jf}v*7#9PWEbnzCENjSoLb|cre=F)i7xN!w zKMx3~1*G580=2#;@q1KLSAiX-8v#Zergl<;^u`nZX!^mK`+lbTFxR3@W>#uCvvvte z^%iBm%j>pk2<2VV70L3wR7BX|;>y0lrt#3-Tyyw(5|r-QyYC9W+~5VOca7+{-I_6; zlJq1ne`JCA>BQoGIk24KNVEH{9&dg~`KoOA*7aSxC&xTB?@U>!-ECHJT029_AIR=M>Xn*}+M+n}*S4Mm zO}0%GOZc^KdDviKly!5Um_84+VGe1Mt1;)eY)LiG{@1gQX(DNo;?fa-jM??O&$U!b z%OyMyALn)6T>kg|>EUH~F1)N>7pYt0@@ipk+l+9br}LvLzgPdkmXSAa{|Ua|s+D@h z17s<^LMT;|0%B4|c(fq_2g5W)Rt)dMT)c#R|CtD54r%1}jHqI;K5lq?Wpu5w2F+4S z@brGknuqA5v8YlDaSD27K-&@k;D^+hl8|73s0Agc5Omo=XO4^Q%#_JO7|M-3O(Y$sb_otLa#TkCb^g0zg@N5J20@CL`St1H_JRbH_x>fE z8BtRqCML9Xdgd-J`i--ShXlq%>~zYe>`_$~sl4@Nm;}dwPex&fA!DR1KQi$6z#fMK zTIO*`M6*7rBrUzg>)afA z7t(m%FzS4!Uvw~^y@0dc5)p)GC}y&G{oL|;#$IIK*r+ou{DR7SzdxIU@I{XbPuSOC zVfvGcQDIuY?y8B3x+*@S_PrVQB4_4u=TXXEA%#wBxV;$+GDG+UBLADvO|*% z{#0QbdbdMcvx19dRZok&sZ8wUwxuPw#3UgkmQo z_2OE3-WXp0Y?e7e>&Gv&Xt42gA#avCaZcVBe0%WvBxjIJEUbH~;YGCNf))sJM7;tw zdv>dq50eROS7D)z>?;Fs8QF%KW9p^;_1Pf1epUBK5@yl>wbo$)bIvR?H%Byg%WycM zp&LMlXFDw|3CScaZG=jn@?}L+v8%fh)JMNS$9XPoP*7^rh>+K9_zuIYEOM{v(yL88 zH&w}b_E3>uwuxV(2|GcsNe09lC+@=yMRP!SWqRYW7qId^@g=12{R5~Wy4G*fofDm zwf=|ERPsfOySv* zr_*{o-x_|H6qED&yt0VfuFG2PbG(T08m*_JhX|&UB)!_zSpd0Lo8{mc(C`8*vus-m zUWP=Vqd_DY>a3I*>2<;>l~1_4kD0+bU9D}9jyBk$G{XJ_c9J1NkxBo^kN2C~e(ON| ztQKl*J@hFBe-gc`a&7kwn`5agiGML!-`NR^V62fp%QvsKsFglnuzzjfW5-1!fjz&+zwlK7ACkVgIAUt0fr`l_Cj$v<3pyMLtcWlSr(4fcC4-{B@e z*1OzF8O=-7TNayj=IN*SmVVNxVL}KH%|fFV&m3Wr=jFdQY~JDU8jjelZed_`MhQ%V z9!{Z4tk_4xUB)X)aGmo2xz|^GVR9r9h)~2)e&bU5T|kT(b-}-6D*<%LAjN~BBsJ&n zLq`C$r8SzHVHI$d^bH9MiV7K)G^C~Q`=r1|%}RT-cTbRe@eO`WQ)2e%dBFY}&#ys9 zf=>{aFj6HLXgfA6+asDbV$FyG6iJq&u-7a>IYhdnUtbqJJRmm!P2{W`Z3D@!Fxd@F zMVVw;g?~mkJv_j(7i7{*EP}r+2jeP6nQ*6buIp_Mf%#L`;+KeZ4=(27AX-^X<4;bY z0%}%7Od%5L0OD`28%jbV82>8|%~=X=)ES6cNIJ33Z&3#^vOFLgh#eW;9>7u=Zh^Wb zTx48PxVylB*P~eqvk6k70?vHNL%c8?bu+*OscE?%(3pCj$iJkr+&5o>1V50DI_ii} z@J}OS-ZY;)@AQGCe%;7prpYnnTv-<_Q+c+(3EN*ZOy7|m1Ik}+IN}c{6pqY@adsLi z2)Hs99GEycJ-mGIJ9%NRH=pC9D|WJRgKoWkZ}iHMnA=i}WsMt&$dPeaiA!a-{Fqen zLiZ;lz+&12hLpt6!8Fok+AX z@ROBWut!V5^h1!ioo_@ipVJGdEsuU4e{fD3!94}gSLV^qG+vBkPHRtPi%4Z*AfKj@6=&ZzOc}q$i z9n3QCTh+HEwxWU4xk;oNol|Ckx+Gshei@gIfl6_f3%=E664$z>*aeM1Z+_$_Tio!CbxI2Az-0GII1wTFGn!{a>A32Rzl?8^2@=CD}XKdz4j4_TD38UR*9$_KawdQAVgFGeXK1N>=tx z3)#tP7!j5KxvH0YyQ2SjKj(e#+xz~$&vTyhJkNQ~b5_8!DKS10vQJiho<>&AnXPq_ zL+;LTbrh};C0!exH`d5qlv@!OD(vfpz#1cQ8-bI|I5aH^-f<9jsDl{d3=)P+oIN@fnL^ zkXyGAYQNST{!Xi|mA_Dc%t`7|lJ6=zBHHRYk(yVIb?-UTr&{d?ZgD;$E%Agp zzt=0*nKt!Q*wNw$l2nd{S<`PGo>d~$MjjF)W4`yhn>0g_^XNRa_A!mU z`mwfqVdpXrHDBvv=AY_rx*B6(ILkX7JIz^BHlkS(%jTjgOe%euRbcvp3%BOIbZPa4 zwikl)5t{lZd#I{7ZCcFgI_#y}iyWsAn#n)DEg(9BnXj$;MTxDB8Zn>fH*D(s@>1qV zDzD%jp8840;jaZ%S^Jg)P4@IE6dJj%8%D0?MsaH@Yj7UpjN)I;KlfBiM@p6Di)sE_B8UZxpDhkJb=gM`G zOsZ$0k9_*B^J3lFwLq5?wW~{S0y=unv->48)k0qsN6Ozu%x%md#(>Tg+uL-kFlssaP);qu%xw=0iV;_Trx%jg1JK50w z4{Hxoi~Xxyd`emi6FZWuvlS`N(5pAWW~-K_PhRA$J@BfGFYRV|T#)+3xuemv2cd`# zK10#(qu95G;~x!JX7x@8$yXFjXk@kCEV`MXFppTmzRuG3g|};sNO9q1WM|GkF-{83 zP-^xbSnr_=Q_o!{Zyah@r8U5fe04#-9XhwqRN(386B$Xr)w70rkF3tn+NN9~awjU) zx)$hIH4$SLMrYx645s)oZ|-o5>ZyT&d!CGAdEzA3@I~6WO6#PZ*=hqwpSlbvWd>ag zJCktu#>|>LS1bptocFH6!8Gw&ydT<<`IkeEu+N^SG^UQOKX%(K=5_U52ycUaP|?ca z8i8E(lXLl}c)oBV_#TT6)4`rGd(Awv&NP&IJRX)deZPlu z4Y8NBJi_S&k8zD9v6qvKGbG?eUwYq6@xzh&G9GP1ubX3)wlF-oEKR24!iW9+UHU4GF$)Ej-%l$qq zTS4yWlt(`LZ_mDR(s(?_PC60QD%{Ah{JGJT^4e+X#PO1@cX2Le7Y#-OBu!^Js>I4j zs3z#0skL!)29A!zw+$X#9!%5`s1zMA`{40Hqo1LQ!P2gY<%JKqpkdLB);<@~D4*zxSwA4?J}rc6I1Ym_gfH$`a50pTD9VkNmQ5zKRWO&tL_WYv*km zUQkO%SEwxrM|BMdG}YTkRn&Excny?zRomK>)moJGm2&iyl+{&v+qp)t(O#Z&a22vW z3`iUTm3wDWu9nDS(3Z%RF+fX&x4ErTwM~1s#HK616;A^q@!*Ir=g!1zVKz1!Y50qp z1se5&dk5DJYEEli)ADuY)@4kUC#|33bjHi3Q9dYmdNU|S?*`(zT+>;dn$&UJ)hA=r44MhJM(PV{ zO>B)9#QECI^mD!Kj@^0gU`|?rJywBd7gH~kf;g%|%V;jB#VqtgVDwA)5uF~Ub!b_D zKH+03N?DNtx8#Zv(G#DHnN~^es5~?tyg7}wdy=N>w(Sg%QzDQT|IYHVMmW2}oIN(W z2y~GCwN{5Z!F}?}t5;wZE|s70%W;S@FLmX~E?etCb73^X>7KrXMOf_k+PApD_Lb)?Q!4UYB6O%weux;y5|MdAa>YI_$+# znGua~!+c7%T!|8)*bm1YE{LR0B67$e5Ax5inVdwZM6f+dR?0ga4K2F(da!ZWvYN73 zL`E*3|Mu&)BR6?d!cu8V++U8i*5bXXV1KHl#df{*aJ}j0(~C6WZpj+Z3eQ}NSZRC{ z=^A`_mTK)Icl*q5R6Sk`J7aIKzIOC@TJk!ugm+mNX|6D;06P)A2d6FZ;H86s+gd#Y?GLr4?lF5Fr>$vT1^GwMSHV1y3 zp6KwhJ0-k?zbD?Hvh(=btcvIeo0&9$r<86NsZ`g{6v?p8ie>Qdg1ywir*SwZqKs?( zFZP6tv0=H%1j~et5-Ttcv?antS=0{U+&xOZcv#`uX9C=n6r7Oe#)UcE)udiBC8JQ& zH2gcgdu8vOVxP*GjyZ6Cf2=!mQ{0)Bvu(Yh4P?GGlKLVz7p?eNB9{`h(?J%{vX*ju z+L}^}K)lRyn3$+phx8cYa)gG!@ft2yigWXEmP0pgr)SUy+RrV~x({Ds=JQX5_#|dX zu0#5cv0k3JHI_>kDld7N%+RhsHr%U$sy)H_5G&J>M+-%<%?(TSm8*+iL{@a{)NPCF zLY@6YEo(}ff-gJWWBu+`@2t(OiE}3Xq$yOd#>@6zH^lzMzAl}_6`fjpn@EN91K)4I zDES;FV+Q9=S|WmdI(q3Yg&yOH9;q^%i+iT9D+MQh&}St}1w7J{BPy5(?}ta35-Zu; zX55v_yz6e+a<9oaJG;0vh(F%VYFOf`Gob~R#G9Gr#_u&ji^YVv57$_gf2bd01Hn{U%QxQqNY(EV{?cTbZjh>NVc5_fRRZ>VeA3 z(hlNkhS|b3nJmmH$uu8eOIl3wf(sLSpR6cfx|y2v`Q8VTb5ct(GwnY6pM{ICXY$Hb z$V5x;n~L`I=zPBS^jQ2oX6*<53PL_A+@p`KQVY38P~9_@i?2U|n-5)?obE7xTTAxw z&Hb+$jyD{m3l6-a>3chA$@sOGRoK$#`cPo(o&PE$x$En{iW-A*_s2g$j@_D5LaUC~WL!DVB z-W_k2s$caM9}CK$6(;0zdD*?Z5D-n4eA?^zTH0Ik42q7Jv_p$64;~JDc-j3sS?r3mMsk$BZ79C%VkFv2V zO0Fm!pOffos`j|;<&^Qcvg7WnPr}YvRe`U2PU%ofoDku0r|yU8Pl^)DQ#KO5TfQ;5 z`Z=<_n7E@V?r@MM*w%PE{buI=h^VLv!NNvbdBM7`2Uyz9Fs7c?4tNfGip%~iesLnj z*mT6*^rSJ-6yN(%4pX*)#-6rRMLfl{ND&F1_yyyTFw<48EbX=&UqRx;3acu9{#W7` z*DHFzxih{!Ynqx-e(eqvDzDfla=SxBUT;cIhbH&vdQRAr2Pz6BHz%BQSTkf@B|fXX zk+|D4rz>gj@~Yz~2d>_*Nl4bsVKU~vo?Glqh`xpFq;{fm70;M}29>tL$)%+NJh>+l zCf>AH`|mLhKEk=O=&qZ{&>8O}#zEUhOe^|(pp@_?|e$VxO%IG8Grr2B?*>KcOtsS9zw0*j=m<5KRr6; zZ9&MOXop8RVFhUm_U5Y;;o&MD$X_=Hk+{sz zm`vi)6c)cH-z!haR_I>(N-0B8=j`LQwK>127+nt4f_x@k-9|s34`yb*FiM`>cNeq7 zXS!=FJ`KLDu~;{egu(_QuUZJ>5CxDX-Le*L-@MyCqcQnUWvrRIfMp z!4F?hxQ8#=S?X$IJ1;!z&LZ8cQWBJNbcurfeYw!7qww3pH^0PUC6a1(yuT*aU;K?? z>}0EF8|m>M9A1S(=Y!-<4rn$X%t?b0VCA2}Ib^CI9>eqE_!4W0-V^4@@6+kC0eIqf z)lP`Kxe-IxkU7sd$=aT8NXX!0G+HRP*Fp1b*Y)hm;0oi=#048l2>+V_em>&s2jl2G zGa|Dx3tnP>JeuiNRR6eVTs$`#Vik~{*B#uTtaA;=6>mV9V1XyIx6pJhMpx4Mw5tsb zm!2;pJvk><;&8ATDc6w-Q|;>xCE2YMk35bWR**S~<9yqP^MaL)>YGL(b>qCrk)N^t*$`^EUS?)Ql4 z^q^_70N+)L26NY1Cc%tnV6cpWe*Z8>_s!CPjrjV5wIctlldLS)FNNO8^!(t<_o^%N z`QwA9=ihQNC{irFSPVX%N)ksC;ZXGCjfTn8%DTxTU+K@;SJm&8Q;3+k@^Pm>_IVyt zm;1asc|1EapCUc9e*lrm=7O*OIFM#_x})b1cbSohb-u(puaTeDd}b)E2${?v*MJp8 zM7mM3NmA;WMhaZ~F1+sad;%x>3!?^sv`eyPV)?q&_=k%qxGs_+9G?gbEjHNIkErVQ zW**4HxxwW;Q5C_pH}j3vp^SsAlJ^9ksp;AkC$v~7cAorXFMPxFhwp0d#1D&4?Gso* z@}E~OHpqVcvHWd@v3W}3eB6z~e0NnRb5>6Awa>HTi)!N+u9sfCgIHl~QM^^oE9BjG zC(>Ldbjg#78b_QkgL-ZOGO_yLgOjya(UJoMb5tmZN^ErCh&hy#BP)rMl+knciM6_vP~`hcp)?OYVJ%(6frSCKOexWRpsN zaagA5t={Uhrc%Kh0%LpBbY^KZ7S!2CzrVG8ESr@O$rCONKcNQo$9bCKPizA}7Oyw& zy-=o2-!MPGopt+K^oRS`I`OF-l^X}wel++_p1huGY+N~dyj@yWcR6%^4eb`nIpSE> zT%>CRbB$fhIf0AyvVTOj1^8QI!n#C*H7uZ)w2M_`xkKuBA=(=5k8)3 zp*`q#*`Ju!;cFI^nMa8c|Hu2MPDES2{?2lUoG$f_urS)7FrxV43L$7Qcm-}ZZ(D#C zJ0qN};0SBSpR?c3UY{p_PNy*sRJ)k5IU^hqb}&~MpPRdfl^Ys=v3M_q!TwbU=n#km zs5=aLXjs4h74SNSKIxYc>ldK_+hXVGb~PMY!R&0H)-b1yY5$<{3|R3ZU(c_$y2gBc zphRD4@C&Iz9CN?8#L&Ch6!pq7Dje)X-A5{YLBM=#@oeB4iL&xtMvWfqMMTU@ISWoMm zDo8mSsu@-8%V5D}C)|HH_|i2FmI)c=vAyh6lL8%|h9rK-)MMWyn6CW@BgIl?rsBM@ zq)nK`a)8q%*3LD%et#B=$v`XCeNhwbCeEw48N^?ONrdYIsEfS1aqsMN2Eoy%Kd1A4y{!WKR zR?$?Z4NVnXo0wK<`ds+xo#uXtpu17r+&4~s|7>AIF7WQ-UG;A5aQn83Ay(QTa}_uC z^>ZSR%9A?m4o@tr%v=&(7xeM-J-&WF#Adj!*GcK49Y{o=yf!mDV8$W-&M|tf`b|g0z ziQ&~JH`F?_ibNVJYl3athbVo`Uy7+6SIf9mt!&R?7L?Lm+aM-;`^5VICTHb1-3$)i zX=5EMj=cxIBnk)}h=tesw5(aUt=e_C(Ci^P8DC3sQP(qJydW}{w{{=_CxP$|{Xv|} z2)?+WNt)wD#e4V-lVZ9^TszJt=N3FR#^={OJ5^{irJD3b%>Qc|gKoB7;{BfLp|qyl z<{l;ggqu3jg!eDqyd2k68I&)QhkaMSPF9e)P=)%{kJH^axg!VW;4@z`#(0c1ijp|y z2r0+!@!Pk5Y71FE4kc2{WA7|$>phtBf#RU3QtUn@p}lAMg>Pi_gaxey7xpqdN4iG>bbz63wUc+{rs9|#4B5{*n(E&4#q&CY0VUx~5T@rYSz-=rj88UXvU*0oFSogwl+k#JA%S zo}#^JsiBnjnYyT-VQSyq@>{xrHSt&c0$}Xk({o3wQ!oEb3rsUkxPk-EIZcfPTf+3AzlBX z3lquvrGwKmPK@8znAw*z75DU=Pf;~44fcpath1G6%);b^7E&c((FHo>ZZ(3wbvpWc zppQ%s5h_Qy^aWYF%h}(d47TfB4Ci_6OU9SUK$1uZFMl}E|2+>oqay#oo6y0|)7KgM z@6D?|=IpxMMKGVbZ2fvtj6`}Rbymv$#9Df7>C?J$bfbQE6z_?UrBIXq`xgq0-*|fqC)k-G?tV^SmD9T{6}U zG5pM+j~I&?7!7)SD$fs^AeT{Uy<@lc2c0lzH0PU-P5zQjBn4C zHivY5pFrA7HYsK6TJr0wSC`IULA#f26n(sm<4gQ=vnH)o+(S+5I@RVR3NL#kzQA4^hl>$DG>n84Y0_l^`Z$$1a=1?%py zX({bvEw12C7$A@{Q#9nVzc7#0`ruOj%nSWnuuGBt234hObU~)3V*R|=9875+6!|?m zuj=>A0ludkjx(;Cr{t$OOX#Kf>bvdeROSoXXGPZ@8037?Cw!GSXo&yroEyV3qrSFr z_e(xq6Zw}K1ws~~D;$0!UbnQoz8dV~JGS%+KJ+aqZHT7j;a(dfc%|LAzSntZm{D)a zbjj+zSScoR!Jhdf9(PV+f!SF`xNqy{UCn-B=TJu8@!n%l zP{N4rn%k`*+z3gd6K!K92f9sYefoZwNYOmWyIoRn#LXx0YHgUsjVF8OrP}qVg&(!5 z*iXCJExXk$dF0(1ejvr~i(PjyT4mzmtq@k{uicJ|4-2771>Y`eC<&+4urCTMP2`Zi zENJxXY+#oZv3Z#^XjN^H1G^jjEnGGj&xM<;ydT`BOlNOf;wM&i%($A!;5Fo8PF>fx z9O2qCx(aLd4U`oT-iLA8$|9rAYE!<9V6|zVOmr|WhE&po-*d4pywv&WVgQ$xsn|-g zh?=cfKnYfon;KARjJ)xtZd+d_1j>wQ%}&-jZ+M%QISRBCyX zY^h-0_1_Z*^_~Cu>-JESt!MtVOm)?WPAn;&0P%_psN0 zT&?+iVJ^hro;+=(j!quscAf&AuHH^=mA+2pHdO(2HBG)30^I63&jq-+)m2-SaSJ@$ z$W<3&M0COzuY|`e

j(Z%G9sdFhlojfFf+EduH`iGwY?@H<$#{tNk~Lh^8Qiq^gs z`p8YNM?qx=6+_gvmE!-==p~f4{){~rPwT1yV*eEo+-*>{f;n%ADv=Ty3#CnD0{@i( z)V*8&FJxa}YP)7jTQ5@R<6A@BkK2%g!>l&Q{bcI4vK|Uk;7>Q0f;zdl`)py0?2N9O z;4MlHkgkW2f{F~t)s#=kYv{_mwP*_P88kJkX|(fbOl)PrQ~?zn8Of{5>z(9N)==1j zon@k{_NauM7^#p&pn^+BH~%*`A164>+0m`H_jfDxx_XfccX8nn^FUI4)nZTm;&ZEq z%toad*`j=W90&6V!|odt}BIdW4WYia)NNmIT$qn;3$H^B#oy8-Kg4+wEM(yx0F@HAJ}*rnwd$ z%BCTwnp)Hzw={!q6Pu%)VW|`MYUM-F3U43HN#nV9DR#^kQ`dDKpLMu2b29#leT!Jg zcRX!#i*(7=R8uH3Kg^_;=b4~7r4Iiqzsi^&yaruNl$FKIWk*iLnrkY39n7q{)mDpj ze)@)pxJqi_T3l^k+c%754vuKeCVLF>V63i4^2<;XK2!sjz$u=N%P^Yc!LgI+0;BmbL-=73n zG$=T8z{a=1afPA71lE?k9R!~r12CxUV1u>IZD3%oR_HkMm$XLR00sgy0?hZf6e@6L zV;dY-OGhX=&`ALvb#4G640H<>s1A7S?SO0$*62XJ5_7O1z()e8s2$G^Okf)zcd$nL zXXDcEpKt93)I-78LBFMG5XcB-sQ(@(MKbl<C?|^7)3&Vssc9tH2bQegAtNB>p#ge z_7HU-ReiuTstnA|?SSeFqGn8D9XwThGXWSXH4p%*q0R;E0BOCwp*C^9mx!kX^An(; z$gp6uv_$WKifq0xCQd6y7d3x?p6UiJm}?Ud{L0AQ0TccgnNCOC!{Y>|pAJQbohsZ7 ztT4Y2MsAB9-lqp{pbHoPssxN)?f~lmrVIZm)pm{_bsQ>xvn{5F8`Sj=zke<3sr!B~ zT<3y{+UxT>AR%1btu0+$5$+i5>7Z;|(m|k0!(cSwMd=~sfxq*&@d&#+%nJGLf)55{ zdJgefQ7}$@<3X2Z_Uzx0H{LKqxM0Ba&TO*k1wF(EoQfz4x6G@5$J{ct=Cic10Z&DM z*%k&0YQBwxRRH-LsHo;D|Kslzz=#bl2f+X-#-T4X06Og=U>wzF%dP(%66WmYZV3mf zWyc4HdpcpjF6BPsp#i*$H}Eb%&RYr`3u`-{y`f&<;x6z$iWPV_1L2GTc*W z2bcz`v8C+6`8%*P)ZGediBY&_Sq5dTKoZUX6jj;$@%|3#;f54~ovWoKW;tA_D2u`e z?B@O<<7k4vBX5y02-z{I#EouI=|F&e6SxJzErNhR#=$IQn{jbN##^v~D|d5)V-PgS zgbS+=;MyJ^T_y!2e@EXK&zvlsE$yJLnE1X~Y2|Yt7|P>==mv=NBY)!?IE-z~~e}TV~a>HoSS2NPiBGot@bRDWlZi)RJ@28O6x= z2UJWsf%6AEL@at^jjr&Kcu7Do$b*!BzZr@H--+ynXC)5=R zZcek=i7LFvn5d5$0=b$9v<0P|W&a0NgtI3M>a`QiH>WP=n1WFUIq#Q8q4_EH-&(rS zi8fGkS2q`^H6Uy0_k!-c1-cWpnGdf28_Aza1hP4fJ2ewLZCHhD zo+_xyD9vQL`R_D6p>7^7$ng;q+3g%J6AIbZ9m)PN^I0)CPf# zw8t-t-i||5(14vme>tQ-IL+;y<(~jtmH@>%iqh=b-Gjm{eSP?l!QDnY`lq{#^l7o> z2U`0L#5bt%=(nUD#qpbSs5jKw0r^-Sx{`)N=w2s*X!ksDcOXHxrFf_88hztRU}T!< zPyD^wtE$UDJQqL0`OP>F1d*eer0Fw8rXQsA#3AYFnsk*Uqvkq*?^!wCw`%Wd2ffkfU;E!k08z?Quu z^3QW|e`saiktj|mkcuVfR#cJO?;6wI()s6+J9JT07v3-22f)ifMFpqL*)7BWo##Ub z=QFL#LI7YFz_}2LG`v6>1j7^t8HfB<@n6!g1-l3~Cb@s=V%f9L9^XOeJ__=asG+vl z{T<=K{Z!!UYmiF(6Zbau5qKrQZ2~hT5frw4i+03ywfY%_@PWw(pOd2#^7tmYT;ggB zsoIc22S$qOye>W3k$|nWvpc3R>WZ|hVI~-!u)stHH3Uzn+!55>-W6(TgMn51p#aV` zAOm3BXbF|zr#qrT-K{Y|Rx-(4`UDtl2aFy@5%1HQ9U+kk`=0{co!Kos+Y$2TIl({7 zuD&Bg8oB<7+*yEX8Als;i|OiQBXmR%gA4|$0>;XLm$M~8&x0rI8r;p^QWyjDR=!bF z>^DL3W(TADB?|y8gaKMBxc-;{P=s<|%C4cUJgmS}+{zO9cMK%9a*sNnNp0UP z_f9rq7?5M1B+VlCZ-@itQN6{Fosq2(AQ%RjnqRov=^m=QZ98}57~ukS28pHr_KBme zT&G+hq4x!rVhVEbsPRa_ze4{agh4I@r7{t$K*yOuMRi6&Uz>gwg9A8AYbM;ZSc3u!2V*V<620*#|1B zUexUj``g=Nz_s;#edjvBd<-h8|6q8tBfBVi@e6!Ar8@)&Y?k$%!GRC`!`rQ6vG^d> zYyxB(QMFj6e@AYSfMDo$wRH8tAP7qc76R$(cmX`BfG5Xyghmca8;di4j-pf4OuX@+ z;nkp`2GW!7cf|dDjN+%|Vc=Spw)rg59FQENYH;h+j_4ape}5mQkea+%j)46vJD3{M zD*ouUGn`I)RshUJ;MkC7Nj8i3E)kKi<{&@n?PLD)8Z=C^itB}SWnkh5`3QU`s;C=h zcE|X}i#A|hfhp{NgL@&a9H0~Y5%xcr+a)@}+1eHA4mICw4TdiDsZjA00yJ0%&@Hn1 zBe!2f)a9zCY>&h16417I}}d!epv9b4EP_|HzT@_@lH&stn+ay~E#2&Yj-?pjpU;&-`T%@7=z7$6 z5XQDUc&M}IhV#Y%ZXrrYH3k$31_&Tm2{%hP`|iLuc5T>#gvg)c!`41f4QbOE2f2}0 z5H6!GLpE~kju5gBFth+fCaXZ}-5+#5Qze`5OZXjdP#uZvYb0fCQ@k z#0%_>1ai*>7<4d40A`8LKE#7;L9r5g3(g7c4t_&Dksbu>Z^5_(f&T2~W;ffN+8v4C zFX3Pi5Bfueo8U1Dy99?@y1D)LY$1Atg#Jj~CjJ+t-QjP@2j$5+B#qsLFA18vqw!ln ze}pgS?+$IUKl-oG|Gh$lE+X{TO*Ux^>;5DA|GjmBP6Pc`|4kZd#{Wp;zdQcXX`o-i zyh#JgVs|wDypkE62Kr@sn>21a>_}ttYCUvV^o#R0VF|!K=p6=`E!XIwO-J8}yW)m!hCL+2R%y0uO00jC|Y|GRt*iMpMIvTj0xU-@o3qHbIO zgqkBmzXE6z^24t1HZKH1Z$J9Y8Jo!aeRjj?uX{AmVbQOr*o58VyBpXomsR{tw#e1i z&0@GSG-^iV5BG$)H?lu~qKK4OHmIS2vMOLNLnx z*Fx0KedlP0S<%7K&!cXFPwohgJe`V;hkn|06VLdI= diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/truffleruby3.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/data/truffleruby3.jar deleted file mode 100644 index 42da0a2ad418c32185d51c24ab303331f98f3e1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180589 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/llvm-toolchain.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/llvm-toolchain.jar deleted file mode 100644 index d744675dae6a30a5bf79273c45010c9485b0521b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1251 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/missing-manifest.zip b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/missing-manifest.zip deleted file mode 100644 index b2a3792e5e5675e7ba456f8d94f9ecfa39dd7de4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4779 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/ruby-11.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/ruby-11.jar deleted file mode 100644 index c9c7add8dab67ca459a86ca0918b7f4d5e8bbba2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180620 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/ruby.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/dir1/ruby.jar deleted file mode 100644 index 9f2b170d0639138b400831dd3faf02f13b3806c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180611 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/emptylist/placeholder b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/emptylist/placeholder deleted file mode 100644 index 8b137891791f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/emptylist/placeholder +++ /dev/null @@ -1 +0,0 @@ - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-replaced-files.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-replaced-files.properties deleted file mode 100644 index c74d041a10c6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-replaced-files.properties +++ /dev/null @@ -1 +0,0 @@ -whatever/lib.jar=fastr,sulong diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component.properties deleted file mode 100644 index bafbf1ca6f9a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component.properties +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Name=y -Bundle-RequireCapability-a=b -Bundle-Symbolic-Name=x -Bundle-Version=2.0 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component2.properties deleted file mode 100644 index aacfdf26c943..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-component2.properties +++ /dev/null @@ -1,5 +0,0 @@ -Bundle-Name=y -Bundle-ProvideCapability-a="foo -Bundle-ProvideCapability-v=V1.1.1 -Bundle-Symbolic-Name=x -Bundle-Version=2.0 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-filelist.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-filelist.properties deleted file mode 100644 index b01a2e269da6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-filelist.properties +++ /dev/null @@ -1,2 +0,0 @@ -FirstPath/directory/ -SecondPath/file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-optional.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-optional.properties deleted file mode 100644 index a423742debba..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/golden-save-optional.properties +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Name=y -Bundle-Symbolic-Name=x -Bundle-Version=2.0 -x-GraalVM-Working-Directories=jre/languages/test/scrap\:jre/lib/test/scrapdir diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/graalvmcore.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/graalvmcore.properties deleted file mode 100644 index 7d2757829620..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/graalvmcore.properties +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Name=GraalVM Core -Bundle-Symbolic-Name=org.graalvm -Bundle-Version=21.1.0 -x-GraalVM-Stability-Level=experimental diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr-2.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr-2.component deleted file mode 100644 index acccf9b82457..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr-2.component +++ /dev/null @@ -1,5 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.fastr -Bundle-Name: Graal FastR implementation -Bundle-Version: 1.0 -Bundle-RequireCapability-graalvm_version: 0.32 -x-GraalVM-Working-Directories=jre/languages/test/scrap\:jre/lib/test/scrapdir diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr.component deleted file mode 100644 index 3d2565e3d4c8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/fastr.component +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.fastr -Bundle-Name: Graal FastR implementation -Bundle-Version: 1.0 -Bundle-RequireCapability-graalvm_version: 0.32 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/org.graalvm.fastr.filelist b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/org.graalvm.fastr.filelist deleted file mode 100644 index 22bd9687800c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/org.graalvm.fastr.filelist +++ /dev/null @@ -1,3 +0,0 @@ - bin/ -bin/R -bin/Rscript \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/ruby.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/ruby.component deleted file mode 100644 index de5590ad3753..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/ruby.component +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.rubt -Bundle-Name: Ruby implementation -Bundle-Version: 1.0 -Bundle-RequireCapability-graalvm_version: 0.32 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/sulong.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list1/sulong.component deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.component deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.filelist b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.filelist deleted file mode 100644 index 22bd9687800c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/fastr.filelist +++ /dev/null @@ -1,3 +0,0 @@ - bin/ -bin/R -bin/Rscript \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/leftover.filelist b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/leftover.filelist deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/ruby.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/ruby.component deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/ruby.filelist b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/ruby.filelist deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/sulong.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list2/sulong.component deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/fastr.component b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/fastr.component deleted file mode 100644 index 3d2565e3d4c8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/fastr.component +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.fastr -Bundle-Name: Graal FastR implementation -Bundle-Version: 1.0 -Bundle-RequireCapability-graalvm_version: 0.32 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/org.graalvm.fastr.filelist b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/org.graalvm.fastr.filelist deleted file mode 100644 index 22bd9687800c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/org.graalvm.fastr.filelist +++ /dev/null @@ -1,3 +0,0 @@ - bin/ -bin/R -bin/Rscript \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/ruby.meta b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/ruby.meta deleted file mode 100644 index 940db989a308..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/list3/ruby.meta +++ /dev/null @@ -1,4 +0,0 @@ -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Name: Ruby implementation -Bundle-Version: 1.0 -Bundle-RequireCapability-graalvm_version: 0.32 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_corrupted.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_corrupted.properties deleted file mode 100644 index c45aeb8f8871..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_corrupted.properties +++ /dev/null @@ -1,5 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -SOURCE=" fastr:f -COMMIT_INFO= - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_ee_simple.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_ee_simple.properties deleted file mode 100644 index 8ea20331e135..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_ee_simple.properties +++ /dev/null @@ -1,4 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -SOURCE=" fastr:f vm-enterprise:d4 -GRAALVM_VERSION="0.30.2" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_noVersion.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_noVersion.properties deleted file mode 100644 index 5a6a61a10d98..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_noVersion.properties +++ /dev/null @@ -1,5 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -SOURCE=" fastr:f -COMMIT_INFO= -#GRAALVM_VERSION="0.30.2" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_simple.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_simple.properties deleted file mode 100644 index 5468e1e22244..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/release_simple.properties +++ /dev/null @@ -1,5 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -SOURCE=" fastr:f3f544be48928c20d68ff403a46affe0522f812c -COMMIT_INFO= -GRAALVM_VERSION="0.30.2" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/replaced-files.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/replaced-files.properties deleted file mode 100644 index 054c535a74e7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/replaced-files.properties +++ /dev/null @@ -1,2 +0,0 @@ -shared/lib/jline.jar=fastr,ruby -share/other/whatever.jar=ruby,sulong diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/Handler.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/Handler.java deleted file mode 100644 index 5733f6a125e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/Handler.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist.test; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.ConnectException; -import java.net.Proxy; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -public class Handler extends URLStreamHandler { - private static Map bindings = Collections.synchronizedMap(new HashMap<>()); - private static Map connections = Collections.synchronizedMap(new HashMap<>()); - private static Map> multiConnections = Collections.synchronizedMap(new HashMap<>()); - private static Set visitedURLs = Collections.synchronizedSet(new HashSet<>()); - private static Map httpProxyConnections = Collections.synchronizedMap(new HashMap<>()); - - public Handler() { - } - - public static void bind(String s, URL u) { - bindings.put(s, u); - } - - public static void bind(String s, URLConnection con) { - connections.put(s, con); - } - - public static void bindMulti(String s, URLConnection con) { - multiConnections.computeIfAbsent(s, (k) -> new ArrayList<>()).add(con); - } - - public static void bindProxy(String s, URLConnection con) { - httpProxyConnections.put(s, con); - } - - public static void clear() { - bindings.clear(); - connections.clear(); - httpProxyConnections.clear(); - multiConnections.clear(); - visitedURLs.clear(); - } - - public static void clearVisited() { - visitedURLs.clear(); - } - - public static boolean isVisited(String u) { - return visitedURLs.contains(u); - } - - public static boolean isVisited(URL u) { - return visitedURLs.contains(u.toString()); - } - - @Override - protected URLConnection openConnection(URL u, Proxy p) throws IOException { - if (p.type() == Proxy.Type.DIRECT) { - return openConnection(u); - } else if (p.type() != Proxy.Type.HTTP) { - return null; - } - URLConnection c = httpProxyConnections.get(u.toString()); - if (c != null) { - return doOpenConnection(u, c); - } else { - throw new ConnectException(u.toExternalForm()); - } - } - - @Override - protected URLConnection openConnection(URL u) throws IOException { - URLConnection c = connections.get(u.toString()); - if (c == null) { - Collection col = multiConnections.getOrDefault(u.toString(), Collections.emptyList()); - Iterator it = col.iterator(); - if (it.hasNext()) { - c = it.next(); - it.remove(); - } - } - return doOpenConnection(u, c); - } - - private static URLConnection doOpenConnection(URL u, URLConnection c) throws IOException { - visitedURLs.add(u.toString()); - if (c != null) { - return c; - } - URL x = bindings.get(u.toString()); - if (x != null) { - return x.openConnection(); - } - throw new FileNotFoundException("Unsupported"); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/TestCatalog.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/TestCatalog.java deleted file mode 100644 index 73f4baa23a1b..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/persist/test/TestCatalog.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist.test; - -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.ce.WebCatalog; - -/** - * Stub that accepts also "test:" URL scheme. - * - * @author sdedic - */ -public class TestCatalog implements SoftwareChannel.Factory { - - @Override - public void init(CommandInput input, Feedback output) { - } - - @Override - public SoftwareChannel createChannel(SoftwareChannelSource spec, CommandInput input, Feedback fb) { - if (spec.getLocationURL().startsWith("test://")) { - WebCatalog c = new WebCatalog(spec.getLocationURL(), spec); - c.init(input, fb); - return c; - } - - return null; - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/CatalogCompatTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/CatalogCompatTest.java deleted file mode 100644 index 19014d8ba837..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/CatalogCompatTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class CatalogCompatTest extends CommandTestBase { - @Rule public ProxyResource proxyResource = new ProxyResource(); - - ComponentCatalog openCatalog(SoftwareChannel ch) throws IOException { - return openCatalog(ch, getLocalRegistry().getGraalVersion()); - } - - ComponentCatalog openCatalog(SoftwareChannel ch, Version v) throws IOException { - ComponentCatalog cc = new CatalogContents(this, ch.getStorage(), getLocalRegistry(), v); - cc.getComponentIDs(); - return cc; - } - - void setupCatalogFormat1(String res) throws Exception { - URL clu = getClass().getResource(res); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - clu); - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - registry = openCatalog(d); - } - - /** - * Checks that the pre 1.0 catalog format is still readable. - * - * @throws Exception - */ - @Test - public void testOldFormatReadable() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormat1.properties"); - assertNotNull(registry.findComponent("ruby")); - assertNotNull(registry.findComponent("python")); - assertNotNull(registry.findComponent("r")); - } - - /** - * Checks that previous versions (RCs) are ignored with the old format. - * - * @throws Exception - */ - @Test - public void testOldFormatIgnoresPrevVersionsAvailable() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormat1.properties"); - - // interprets user input for 'available' - Version gv = getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.INSTALLABLE); - - List infos; - - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("python", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("r", selector, verbose)); - assertEquals(1, infos.size()); - } - - /** - * Checks that previous versions (RCs) are ignored with the old format. - * - * @throws Exception - */ - @Test - public void testOldFormatIgnoresPrevVersionsMostRecent() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormat1.properties"); - - // copied from CatalogIterable, this is what interprets user input for install - Version gv = getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.MOSTRECENT); - - List infos; - - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("python", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("r", selector, verbose)); - assertEquals(1, infos.size()); - } - - /** - * Checks that future versions in OLD format are not accepted. - */ - @Test - public void testOldFormatIgnoresFutureVersionsAvailable() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormat2.properties"); - - // this is what interprets user input for 'available' - Version gv = getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.INSTALLABLE); - - List infos; - - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("python", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("r", selector, verbose)); - assertEquals(1, infos.size()); - } - - /** - * Checks that future versions in OLD format are not accepted. - */ - @Test - public void testOldFormatIgnoresFutureVersionsInstall() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormat2.properties"); - - // copied from CatalogIterable, this is what interprets user input for install - Version gv = getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.MOSTRECENT); - - List infos; - - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("python", selector, verbose)); - assertEquals(1, infos.size()); - infos = new ArrayList<>(registry.loadComponents("r", selector, verbose)); - assertEquals(1, infos.size()); - } - - /** - * Checks that if a catalog mixes in new-format entries, they're read and processed for new - * versions, too. - * - * @throws Exception - */ - @Test - public void testMixedFormatAllowsFutureVersions() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormatMix.properties"); - - List infos; - - Version gv = getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.INSTALLABLE); - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - - assertNotNull(infos); - assertEquals(3, infos.size()); - - Collections.sort(infos, ComponentInfo.versionComparator()); - - ComponentInfo one = infos.get(0); - ComponentInfo two = infos.get(1); - ComponentInfo three = infos.get(2); - assertEquals("1.0.0", one.getVersionString()); - assertEquals("1.0.1.0", two.getVersionString()); - assertEquals("1.0.2.0-1", three.getVersionString()); - } - - /** - * Checks that install will attempt to install the most recent stuff for the current release. - * Will add the same-release component to existing instalation - */ - @Test - public void testMixedFormatInstallSameRelease() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormatMix.properties"); - - List infos; - - Version gv = getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.MOSTRECENT); - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - - assertNotNull(infos); - assertEquals(1, infos.size()); - ComponentInfo one = infos.get(0); - assertEquals("1.0.0", one.getVersionString()); - } - - /** - * Checks that install will attempt to install the most recent stuff with mixed catalog. Will - * upgrade the installation - */ - @Test - public void testMixedFormatInstallUpgrades() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0"); - setupCatalogFormat1("catalogFormatMix.properties"); - - List infos; - - Version gv = getLocalRegistry().getGraalVersion(); - registry.setAllowDistUpdate(true); - Version.Match selector = gv.match(Version.Match.Type.MOSTRECENT); - // check that versions 1.0.0-rcX are ignored for version 1.0.0 - infos = new ArrayList<>(registry.loadComponents("ruby", selector, verbose)); - - assertNotNull(infos); - assertEquals(1, infos.size()); - ComponentInfo one = infos.get(0); - assertEquals("1.0.2.0-1", one.getVersionString()); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/FileDownloaderTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/FileDownloaderTest.java deleted file mode 100644 index 192b90ebf168..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/FileDownloaderTest.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import org.graalvm.component.installer.ChunkedConnection; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.persist.NetworkTestBase; -import org.graalvm.component.installer.persist.test.Handler; -import org.junit.Assert; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Test; -import java.net.SocketException; - -public class FileDownloaderTest extends NetworkTestBase { - - class FA extends FeedbackAdapter { - - @Override - public String l10n(String key, Object... params) { - switch (key) { - case "MSG_DownloadProgress@": - return "[ ]"; - case "MSG_DownloadProgressSignChar@": - return "#"; - } - return key; - } - - } - - @Before - @Override - public void setUp() throws Exception { - super.setUp(); - delegateFeedback(new FA()); - Handler.clear(); - } - - @Test - public void testDownloadExistingFile() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - Handler.bind("test://graalvm.io/download/truffleruby.zip", - clu); - - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - FileDownloader dn = new FileDownloader("test", - u, this); - dn.download(); - - File local = dn.getLocalFile(); - assertTrue(local.exists()); - assertTrue(local.isFile()); - - URLConnection c = clu.openConnection(); - assertEquals(c.getContentLengthLong(), local.length()); - } - - @Test - public void testDownloadComputeDigest() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - Handler.bind("test://graalvm.io/download/truffleruby.zip", - clu); - - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - FileDownloader dn = new FileDownloader("test", - u, this); - dn.setShaDigest(new byte[0]); - dn.download(); - - byte[] check = SystemUtils.toHashBytes("b649fe3b9309d1b3ae4d2dbae70eebd4d2978af32cd1ce7d262ebf7e0f0f53fa"); - assertArrayEquals(check, dn.getReceivedDigest()); - } - - class Check extends FA { - int state; - boolean verbose = true; - int cnt = 0; - StringBuilder bar = new StringBuilder("[ ]"); - String bcksp = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; - - @Override - public boolean verbosePart(String bundleKey, Object... params) { - switch (state) { - case 0: - if ("MSG_DownloadReceivingBytes".equals(bundleKey)) { - state++; - } - break; - } - return super.verbosePart(bundleKey, params); - } - - @Override - public void output(String bundleKey, Object... params) { - if (state == 0 && verbose) { - Assert.assertNotEquals("MSG_Downloading", bundleKey); - } - } - - @Override - public boolean verboseOutput(String bundleKey, Object... params) { - switch (state) { - case 0: - assertEquals("MSG_DownloadingVerbose", bundleKey); - break; - case 5: - if ("MSG_DownloadingDone".equals(bundleKey)) { - state++; - } - break; - } - return super.verboseOutput(bundleKey, params); - } - - @Override - public boolean verbatimPart(String msg, boolean beVerbose) { - switch (state) { - case 1: - assertEquals(bar.toString(), msg); - state++; - break; - case 3: - cnt++; - bar.setCharAt(cnt, '#'); - assertEquals(bar.toString(), msg); - if (cnt >= 20) { - state = 4; - } else { - state = 2; - } - break; - case 2: - assertEquals(msg, bcksp); - state++; - break; - case 4: - assertEquals(msg, bcksp); - state++; - break; - } - return super.verbatimPart(msg, beVerbose); - } - - } - - @Test - public void testDownloadVerboseMessages() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - Handler.bind("test://graalvm.io/download/truffleruby.zip", - clu); - - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Check check = new Check(); - delegateFeedback(check); - FileDownloader dn = new FileDownloader("test", - u, this); - dn.setVerbose(true); - dn.setDisplayProgress(true); - dn.sizeThreshold = 10; - verbose = true; - dn.download(); - - assertEquals(6, check.state); - } - - /** - * Checks that slow proxy will be used although the direct connection has failed already. - * - * @throws Exception - */ - @Test - public void testDownloadSlowProxy() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - - ChunkedConnection proxyConnect = new ChunkedConnection( - u, - clu.openConnection()) { - @Override - public void connect() throws IOException { - try { - // called twice, default timeout is 5 secs - Thread.sleep(1000); - } catch (InterruptedException ex) { - } - super.connect(); - } - - }; - - Handler.bindProxy(u.toString(), proxyConnect); - Check check = new Check(); - delegateFeedback(check); - FileDownloader dn = new FileDownloader("test", - u, this); - ProxyConnectionFactory pcf = new ProxyConnectionFactory(this, u); - dn.setConnectionFactory(pcf); - - verbose = true; - dn.setVerbose(true); - dn.setDisplayProgress(true); - - pcf.envHttpProxy = "http://localhost:11111"; - pcf.envHttpsProxy = "http://localhost:11111"; - - dn.download(); - URLConnection c = clu.openConnection(); - assertEquals(c.getContentLengthLong(), dn.getLocalFile().length()); - } - - /** - * Checks that if proxy fails, the direct connection, although it connects later, will be used. - * - * @throws Exception - */ - @Test - public void testDownloadFailedProxy() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - - ChunkedConnection directConnect = new ChunkedConnection( - u, - clu.openConnection()) { - @Override - public void connect() throws IOException { - try { - Thread.sleep(2000); - } catch (InterruptedException ex) { - } - super.connect(); - } - - }; - - Handler.bind(u.toString(), directConnect); - Check check = new Check(); - check.verbose = false; - delegateFeedback(check); - FileDownloader dn = new FileDownloader("test", - u, this); - dn.setVerbose(true); - dn.setDisplayProgress(true); - - ProxyConnectionFactory pcf = new ProxyConnectionFactory(this, u); - dn.setConnectionFactory(pcf); - - pcf.envHttpProxy = "http://localhost:11111"; - pcf.envHttpsProxy = "http://localhost:11111"; - - synchronized (directConnect) { - directConnect.nextChunk = 130 * 1024; - directConnect.readException = new FileNotFoundException(); - } - - exception.expect(FileNotFoundException.class); - dn.download(); - } - - /** - * Checks that a proxy connection which results in HTTP 500 will not override delayed direct - * connection. - * - * @throws Exception - */ - @Test - public void testDownloadProxy500() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - - ChunkedConnection directConnect = new ChunkedConnection( - u, - clu.openConnection()) { - @Override - public void connect() throws IOException { - try { - Thread.sleep(2000); - } catch (InterruptedException ex) { - } - super.connect(); - } - }; - - HttpURLConnection proxyCon = new HttpURLConnection(u) { - @Override - public void disconnect() { - } - - @Override - public boolean usingProxy() { - return true; - } - - @Override - public void connect() throws IOException { - responseCode = 500; - } - }; - - Handler.bind(u.toString(), directConnect); - Handler.bindProxy(u.toString(), proxyCon); - Check check = new Check(); - check.verbose = false; - delegateFeedback(check); - FileDownloader dn = new FileDownloader("test", - u, this); - dn.setVerbose(true); - dn.setDisplayProgress(true); - - ProxyConnectionFactory pcf = new ProxyConnectionFactory(this, u); - dn.setConnectionFactory(pcf); - - pcf.envHttpProxy = "http://localhost:11111"; - pcf.envHttpsProxy = "http://localhost:11111"; - - dn.download(); - } - - @Test - public void testDownloadFailure() throws Exception { - URL clu = getClass().getResource("data/truffleruby2.jar"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - - ChunkedConnection conn = new ChunkedConnection( - u, - clu.openConnection()); - Handler.bind(u.toString(), conn); - Check check = new Check(); - check.verbose = false; - delegateFeedback(check); - FileDownloader dn = new FileDownloader("test", - u, this); - dn.setVerbose(true); - dn.setDisplayProgress(true); - synchronized (conn) { - conn.nextChunk = 130 * 1024; - - ProxyConnectionFactory pcf = new ProxyConnectionFactory(this, u); - dn.setConnectionFactory(pcf); - - pcf.envHttpProxy = null; - pcf.envHttpsProxy = null; - } - - AtomicReference exc = new AtomicReference<>(); - Thread t = new Thread() { - @Override - public void run() { - try { - dn.download(); - } catch (Throwable x) { - exc.set(x); - } - } - }; - - t.start(); - - assertTrue(conn.reachedSem.tryAcquire(2, TimeUnit.SECONDS)); - // conn.reachedSem.acquire(); - conn.readException = new SocketException(); - conn.nextSem.release(); - t.join(1000); - // t.join(); - assertFalse(t.isAlive()); - assertTrue(exc.get() instanceof IOException); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/GraalEditionListTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/GraalEditionListTest.java deleted file mode 100644 index 53c8dc2d5534..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/GraalEditionListTest.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Properties; -import org.graalvm.component.installer.CommandTestBase; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.model.GraalEdition; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class GraalEditionListTest extends CommandTestBase { - - private void loadReleaseFile(String name) throws IOException { - try (InputStream stm = getClass().getResourceAsStream("data/" + name)) { - Properties props = new Properties(); - props.load(stm); - props.stringPropertyNames().forEach((s) -> { - this.storage.graalInfo.put(s, props.getProperty(s)); - }); - } - } - - /** - * Checks that GraalVM 20.x style single property is parsed properly. Multiple SoftwareChannel - * Sources should be created, but just one Edition, the default one. - * - * @throws Exception - */ - @Test - public void testParseRelease20CatalogProperty() throws Exception { - loadReleaseFile("release20ce.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setDefaultCatalogSpec(storage.graalInfo.get(CommonConstants.RELEASE_CATALOG_KEY)); - List eds = list.editions(); - assertFalse(eds.isEmpty()); - assertEquals(1, eds.size()); - GraalEdition ge = eds.get(0); - - assertSame(list.getDefaultEdition(), ge); - assertEquals("Expected ce edition", "ce", ge.getId()); - assertEquals("Label from graal caps should be capitalized", "CE", ge.getDisplayName()); - } - - @Test - public void testParseRelease20EEWithLabel() throws Exception { - // this one contains multiple - loadReleaseFile("release20ee.properties"); - // substitute "ee", since that's what the DirectoryStorage does in presence of - // 'vm-enterprise' now: - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ee"); - - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setDefaultCatalogSpec(storage.graalInfo.get(CommonConstants.RELEASE_CATALOG_KEY)); - List eds = list.editions(); - assertFalse(eds.isEmpty()); - assertEquals(1, eds.size()); - - GraalEdition ge = eds.get(0); - assertSame(list.getDefaultEdition(), ge); - assertEquals("Expected ee for vm-enterprise", "ee", ge.getId()); - assertEquals("Unqualified label should be picked up", "Enterprise Edition", ge.getDisplayName()); - - List sources = ge.getSoftwareSources(); - assertEquals("Multiple software sources must be read", 3, sources.size()); - assertEquals("Expected decreasing priority", 2, sources.get(1).getPriority()); - } - - /** - * Checks multi-property definition parsing from the release file. The default property may be - * present, but will be ignored. - * - * @throws Exception - */ - @Test - public void testParseRelease20MultiCatalogDefs() throws Exception { - // this one contains multiple - loadReleaseFile("release20ceWithEE.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setDefaultCatalogSpec(storage.graalInfo.get(CommonConstants.RELEASE_CATALOG_KEY)); - List eds = list.editions(); - assertFalse(eds.isEmpty()); - assertEquals(2, eds.size()); - - GraalEdition ge = eds.get(0); - assertSame(list.getDefaultEdition(), ge); - assertEquals("Expected ce edition to be the default/installed", "ce", ge.getId()); - assertEquals("Label from graal caps should be capitalized", "CE", ge.getDisplayName()); - - List sources = ge.getSoftwareSources(); - assertEquals("CE edition has single source", 1, sources.size()); - - ge = eds.get(1); - assertEquals("Enterprise Edition must be present", "ee", ge.getId()); - assertEquals("Enterprise label should be parsed out", "Enterprise Edition", ge.getDisplayName()); - sources = ge.getSoftwareSources(); - assertEquals("EE has more sources", 2, sources.size()); - assertEquals("Expected decreasing priority", 2, sources.get(1).getPriority()); - - assertSame(ge, list.getEdition("ee")); - } - - /** - * Check function of the 'override' switch: the catalog software sources from Graal-20 release - * file should be ignored. - * - * @throws Exception - */ - @Test - public void testCheckUserUserOverride20() throws Exception { - // this one contains multiple - loadReleaseFile("release20ceWithEE.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setDefaultCatalogSpec(storage.graalInfo.get(CommonConstants.RELEASE_CATALOG_KEY)); - list.setOverrideCatalogSpec("http://somewhere/catalog.properties|http://somewhereElse/catalog.properties"); - - List eds = list.editions(); - assertEquals(1, eds.size()); - GraalEdition ge = eds.get(0); - assertEquals("Expected default edition", "ce", ge.getId()); - List sources = ge.getSoftwareSources(); - assertEquals("Expected 2 sources from override", 2, sources.size()); - assertTrue(sources.stream().allMatch(s -> s.getLocationURL().contains("somewhere"))); - assertEquals(2, sources.get(1).getPriority()); - } - - @Test - public void testCheck21MultipleProperties() throws Exception { - loadReleaseFile("release21ce.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setDefaultCatalogSpec(storage.graalInfo.get(CommonConstants.RELEASE_CATALOG_KEY)); - - List eds = list.editions(); - assertEquals(1, eds.size()); - GraalEdition ge = eds.get(0); - List sources = ge.getSoftwareSources(); - assertEquals("Expected default edition", "ce", ge.getId()); - assertEquals("Expected 2 sources from multiproperties", 2, sources.size()); - - } - - @Test - public void testCheck21MultipleEditions() throws Exception { - loadReleaseFile("release21ceWithEE.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setDefaultCatalogSpec(storage.graalInfo.get(CommonConstants.RELEASE_CATALOG_KEY)); - - List eds = list.editions(); - assertEquals(2, eds.size()); - assertSame(list.getDefaultEdition(), eds.get(0)); - assertSame(list.getDefaultEdition(), list.getEdition("")); - - GraalEdition ge = list.getEdition("ce"); - assertSame(list.getDefaultEdition(), ge); - assertSame(list.getEdition(""), ge); - assertFalse("CE".equalsIgnoreCase(ge.getDisplayName())); - - List sources = ge.getSoftwareSources(); - assertEquals(2, sources.size()); - assertNotNull(sources.get(0).getLabel()); - assertTrue(sources.get(0).getLabel().contains("CE 8")); - assertNotNull(sources.get(1).getLabel()); - assertTrue(sources.get(1).getLabel().contains("CE 11")); - - // check lowercasing - ge = list.getEdition("eE"); - sources = ge.getSoftwareSources(); - assertEquals(3, sources.size()); - assertFalse("EE".equalsIgnoreCase(ge.getDisplayName())); - - String u = sources.get(0).getLocationURL(); - assertTrue(u.startsWith("gds:")); - assertTrue(sources.get(0).getLabel().contains("GDS")); - - u = sources.get(1).getLocationURL(); - assertTrue(u.contains("java8.properties")); - assertTrue(sources.get(1).getLabel().contains("Github")); - assertEquals("valueY", sources.get(1).getParameter("paramx")); - - u = sources.get(2).getLocationURL(); - assertTrue(u.contains("ee-extras")); - assertTrue(sources.get(2).getLabel().contains("experimental")); - } - - /** - * Check function of the 'override' switch: the catalog software sources from release file - * should be ignored. This test checks function for multiple-property definition, even in the - * presence of single-property definition which should be ignored. - * - * @throws Exception - */ - @Test - public void testCheckUserUserOverride21() throws Exception { - loadReleaseFile("release21ce.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - checkOverrideCommon(); - } - - private void checkOverrideCommon() throws Exception { - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - list.setOverrideCatalogSpec("https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8x.properties"); - - List eds = list.editions(); - assertEquals(1, eds.size()); - assertEquals(list.getDefaultEdition(), eds.get(0)); - - GraalEdition ge = eds.get(0); - assertEquals("ce", ge.getId()); - assertSame(ge, list.getEdition(null)); - - List channels = ge.getSoftwareSources(); - assertEquals(1, channels.size()); - assertTrue(channels.get(0).getLocationURL().endsWith("java8x.properties")); - } - - /** - * Checks that explicit URL (commandline) will override multi-edition setup. This must set up - * the default edition to the set of software channes from the explicit URL. - * - * @throws Exception - */ - @Test - public void testOverrideOneOverMultipleEditions() throws Exception { - loadReleaseFile("release21ceWithEE.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - checkOverrideCommon(); - } - - @Test - public void testEmptyReleaseInitializesOK() throws Exception { - loadReleaseFile("emptyRelease.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ee"); - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - - GraalEdition ge = list.getDefaultEdition(); - assertNotNull(ge); - assertEquals("ee", ge.getId()); - assertEquals(0, ge.getSoftwareSources().size()); - } - - /** - * Checks that exception is thrown when accessing undefined edition. - */ - @Test - public void testNonExistentEditionFails() throws Exception { - loadReleaseFile("release21ceWithEE.properties"); - storage.graalInfo.put(CommonConstants.CAP_EDITION, "ce"); - GraalEditionList list = new GraalEditionList(this, this, getLocalRegistry()); - - assertNotNull(list.getEdition("ee")); - assertNotNull(list.getEdition("ce")); - try { - assertNull(list.getEdition("fake")); - fail("Expected exception"); - } catch (FailedOperationException ex) { - // expected - } - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/ProxyConnectionFactoryTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/ProxyConnectionFactoryTest.java deleted file mode 100644 index 472de647b7af..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/ProxyConnectionFactoryTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.net.InetSocketAddress; -import java.net.URL; -import java.util.List; - -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.persist.ProxyResource; -import org.graalvm.component.installer.remote.ProxyConnectionFactory.Connector; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; - -/** - * - * @author sdedic - */ -public class ProxyConnectionFactoryTest extends TestBase { - - @Rule public ProxyResource proxyResource = new ProxyResource(); - - private static final String RESOURCE_URL = "test://remote-resource"; - private static final String HTTP_PROXY_ADDRESS = "http://proxy:80"; - - private ProxyConnectionFactory instance; - - @Before - public void setUp() throws Exception { - URL u = SystemUtils.toURL(RESOURCE_URL); - instance = new ProxyConnectionFactory(this, u); - // override proxies which may be loaded from testsuite environment: - instance.setProxy(true, null); - instance.setProxy(false, null); - } - - /** - * If no proxy is set, just direct connector is used. - */ - @Test - public void testNoProxy() throws Exception { - List cons = instance.makeConnectors(null, null); - assertEquals(1, cons.size()); - Connector c = cons.get(0); - assertTrue(c.isDirect()); - } - - private static void assertDirectConnector(List lst) { - assertTrue(lst.stream().filter(c -> c.isDirect()).findFirst().isPresent()); - } - - private static Connector findConnector(List lst, String proxyHost) { - for (Connector c : lst) { - InetSocketAddress a = c.getProxyAddress(); - if (a != null && proxyHost.equals(a.getHostName())) { - return c; - } - } - return null; - } - - @Test - public void testHttpProxy() throws Exception { - List cons = instance.makeConnectors(HTTP_PROXY_ADDRESS, null); - assertEquals(2, cons.size()); - assertDirectConnector(cons); - assertNotNull(findConnector(cons, "proxy")); - } - - @Test - public void testHttpsProxy() throws Exception { - List cons = instance.makeConnectors(null, HTTP_PROXY_ADDRESS); - assertEquals(2, cons.size()); - assertDirectConnector(cons); - assertNotNull(findConnector(cons, "proxy")); - } - - @Test - public void testBothProxiesSame() throws Exception { - List cons = instance.makeConnectors(HTTP_PROXY_ADDRESS, HTTP_PROXY_ADDRESS); - assertEquals(2, cons.size()); - assertDirectConnector(cons); - assertNotNull(findConnector(cons, "proxy")); - } - - @Test - public void testHttpAndHttpsDifferent() throws Exception { - List cons = instance.makeConnectors(HTTP_PROXY_ADDRESS, "http://securerproxy:1111"); - assertEquals(3, cons.size()); - assertDirectConnector(cons); - assertNotNull(findConnector(cons, "proxy")); - assertNotNull(findConnector(cons, "securerproxy")); - } - - @Test - public void testNamedProxyWithSpace() throws Exception { - List cons = instance.makeConnectors(" proxy:80", null); - assertEquals(2, cons.size()); - assertDirectConnector(cons); - - Connector c = findConnector(cons, "proxy"); - assertNotNull(c); - assertEquals(80, c.getProxyAddress().getPort()); - } - - String errorMessage; - - @Test - public void testMalformedProxy() throws Exception { - class F extends FeedbackAdapter { - - @Override - public void error(String key, Throwable t, Object... params) { - super.error(key, t, params); - errorMessage = key; - } - } - F f = new F(); - delegateFeedback(f); - List cons = instance.makeConnectors(":proxy:80", null); - assertEquals(1, cons.size()); - assertDirectConnector(cons); - - // check that warning about illegal proxy was printed - assertTrue(errorMessage.startsWith("WARN_")); - } - - @Test - public void testNumericWithProtocol() throws Exception { - List cons = instance.makeConnectors("http://127.0.0.2:1080", null); - assertEquals(2, cons.size()); - assertDirectConnector(cons); - - Connector c = findConnector(cons, "127.0.0.2"); - assertNotNull(c); - assertEquals(1080, c.getProxyAddress().getPort()); - } - - @Test - public void testNumericNoProtocol() throws Exception { - List cons = instance.makeConnectors("127.0.0.2:1080", null); - assertEquals(2, cons.size()); - assertDirectConnector(cons); - - Connector c = findConnector(cons, "127.0.0.2"); - assertNotNull(c); - assertEquals(1080, c.getProxyAddress().getPort()); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteCatalogDownloaderTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteCatalogDownloaderTest.java deleted file mode 100644 index 771dcc348120..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteCatalogDownloaderTest.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.net.ConnectException; -import java.net.URL; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.MockURLConnection; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.persist.NetworkTestBase; -import org.graalvm.component.installer.persist.test.Handler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import org.junit.Test; - -public class RemoteCatalogDownloaderTest extends NetworkTestBase { - - ComponentCatalog openCatalog(SoftwareChannel ch) throws IOException { - return openCatalog(ch, getLocalRegistry().getGraalVersion()); - } - - ComponentCatalog openCatalog(SoftwareChannel ch, Version v) throws IOException { - ComponentCatalog cc = new CatalogContents(this, ch.getStorage(), getLocalRegistry(), v); - cc.getComponentIDs(); - return cc; - } - - @Test - public void testDownloadCatalogBadGraalVersion() throws Exception { - URL clu = getClass().getResource("catalog.properties"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - clu); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - exception.expect(IncompatibleException.class); - exception.expectMessage("REMOTE_UnsupportedGraalVersion"); - openCatalog(d); - } - - @Test - public void testDownloadCatalogCorrupted() throws Exception { - URL clu = getClass().getResource("catalogCorrupted.properties"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - clu); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_CorruptedCatalogFile"); - openCatalog(d); - } - - private void loadRegistry() throws Exception { - URL clu = getClass().getResource("catalog.properties"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - clu); - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - registry = openCatalog(d); - } - - @Test - public void testDownloadCatalogGood() throws Exception { - loadRegistry(); - assertNotNull(registry); - } - - @Test - public void testRemoteComponents() throws Exception { - loadRegistry(); - assertEquals(2, registry.getComponentIDs().size()); - - assertNotNull(registry.findComponent("r")); - assertNotNull(registry.findComponent("ruby")); - } - - @Test - public void testDownloadCorruptedCatalog() throws Exception { - URL clu = getClass().getResource("catalogCorrupted.properties"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - clu); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_CorruptedCatalogFile"); - openCatalog(d); - } - - @Test - public void testCannotConnectCatalog() throws Exception { - URL clu = getClass().getResource("catalogCorrupted.properties"); - URL u = SystemUtils.toURL("test://graalvm.io/download/truffleruby.zip"); - Handler.bind(u.toString(), - new MockURLConnection(clu.openConnection(), u, new ConnectException())); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, u); - exception.expect(FailedOperationException.class); - exception.expectMessage("REMOTE_ErrorDownloadCatalogProxy"); - openCatalog(d); - } - - RemoteCatalogDownloader rcd; - - private void setupJoinedCatalog(String firstPart) throws IOException { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0.0"); - URL u1 = SystemUtils.toURL("test://graalvm.io/catalog1.properties"); - URL u2 = SystemUtils.toURL("test://graalvm.io/catalog2.properties"); - - URL clu1 = getClass().getResource(firstPart); - URL clu2 = getClass().getResource("catalogMultiPart2.properties"); - - Handler.bind(u1.toString(), clu1); - Handler.bind(u2.toString(), clu2); - - String list = String.join("|", u1.toString(), u2.toString()); - - rcd = new RemoteCatalogDownloader(this, this, list); - } - - private static ComponentInfo findComponent(ComponentCollection col, String id) { - Collection infos = col.loadComponents(id, Version.NO_VERSION.match(Version.Match.Type.GREATER), false); - return infos == null || infos.isEmpty() ? null : infos.iterator().next(); - } - - /** - * Checks that if a single catalog does not correspond to graalvm version, other catalogs will - * be read. - * - * @throws Exception - */ - @Test - public void testSingleNonMatchingCatalogIgnored() throws Exception { - setupJoinedCatalog("catalogMultiPart1.properties"); - ComponentCatalog col = openCatalog(rcd); - - // need to incorporate requirements, too... they are tested in CatalogIterable - CatalogIterable catIt = new CatalogIterable(this, this); - catIt.setRemoteRegistry(col); - - textParams.add("r"); - textParams.add("ruby"); - textParams.add("python"); - - Iterator iter = catIt.iterator(); - - ComponentParam p = iter.next(); - ComponentInfo info; - - assertNotNull(p); - info = p.createMetaLoader().getComponentInfo(); - assertEquals("1.0.0.0", info.getVersion().toString()); - - p = iter.next(); - assertNotNull(p); - info = p.createMetaLoader().getComponentInfo(); - assertEquals("1.0.0.0", info.getVersion().toString()); - - // python cannot be found, an exception expected - assertTrue(iter.hasNext()); - try { - p = iter.next(); - fail("No python for 1.0.0"); - } catch (FailedOperationException ex) { - - } - } - - /** - * Checks that multiple catalogs are merged together. - */ - @Test - public void testMultipleCatalogsJoined() throws Exception { - setupJoinedCatalog("catalogMultiPart1Mergeable.properties"); - ComponentCollection col = openCatalog(rcd); - assertNotNull(findComponent(col, "r")); - assertNotNull(findComponent(col, "ruby")); - assertNotNull(findComponent(col, "python")); - } - - /** - * Checks that simple explicit URL given 'the old way' will define a catalog that will be - * loaded. - * - * @throws Exception - */ - @Test - public void testParseCatalogOverride() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - String single = "test://graalv.org/test/catalog.properties"; - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, single); - List sources = d.getChannelSources(); - assertNotNull(sources); - assertEquals(1, sources.size()); - assertEquals(single, sources.get(0).getLocationURL()); - - URL clu1 = getClass().getResource("catalogMultiVersions.properties"); - - Handler.bind(single, clu1); - - ComponentStorage store = d.getStorage(); - Set ids = store.listComponentIDs(); - assertTrue(ids.contains("ruby")); - assertTrue(Handler.isVisited(SystemUtils.toURL(single))); - } - - @Test - public void testParseCatalogOverrideParameters() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - String url = "test://graalv.org/test/catalog.properties"; - String single = url + "?linux=a&macOS=a+b&windows="; - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, single); - List sources = d.getChannelSources(); - assertNotNull(sources); - assertEquals(1, sources.size()); - - SoftwareChannelSource src = sources.get(0); - assertEquals(url, src.getLocationURL()); - - assertEquals("a", src.getParameter("linux")); - assertEquals("a b", src.getParameter("macOS")); - assertEquals("", src.getParameter("windows")); - } - - private static final String FIRST_CATALOG_URL = "test://graalv.org/test/catalog.properties"; - private static final String SECOND_CATALOG_URL = "test://graalv.org/test/catalog.2.properties"; - - private void checkMultipleCatalogResults(RemoteCatalogDownloader d) throws Exception { - URL clu1 = getClass().getResource("catalogMultiPart1.properties"); - Handler.bind(FIRST_CATALOG_URL, clu1); - - URL clu2 = getClass().getResource("catalogMultiPart3.properties"); - Handler.bind(SECOND_CATALOG_URL, clu2); - - ComponentStorage store = d.getStorage(); - Set ids = store.listComponentIDs(); - - assertTrue(ids.contains("ruby")); - assertTrue(ids.contains("r")); - } - - /** - * Checks that multiple URLs given 'the old way' will define a catalog that will be loaded. - * Checks that parameters of the URL will be initialized. - * - * @throws Exception - */ - @Test - public void testParseMultipleCatalogOverride() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.1.0"); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, String.join("|", FIRST_CATALOG_URL, SECOND_CATALOG_URL)); - checkMultipleCatalogResults(d); - } - - /** - * Checks that multiple catalogs defined in the release file are merged together and contain - * correct metadata. - * - * @throws Exception - */ - @Test - public void testParseNewReleaseCatalogMulti() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.1.0"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "1_url", "test://graalv.org/test/catalog.properties"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "1_label", "First part"); - - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "3_url", "test://graalv.org/test/catalog.2.properties"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "3_label", "Second part"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "3_linux", "a"); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, (String) null); - checkMultipleCatalogResults(d); - - List sources = d.getChannelSources(); - assertEquals(2, sources.size()); - assertEquals("First part", sources.get(0).getLabel()); - assertEquals("a", sources.get(1).getParameter("linux")); - } - - /** - * Checks that catalog entries in environment win over release file ones. - * - * @throws Exception - */ - @Test - public void testEnvironmentMultiCatalogWins() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.1.0"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "1_url", "test://graalv.org/test/catalog.properties"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "1_label", "First part"); - - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "3_url", "test://graalv.org/test/catalog.2.properties"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "3_label", "Second part"); - storage.graalInfo.put(CommonConstants.CAP_CATALOG_PREFIX + "3_linux", "a"); - - RemoteCatalogDownloader d = new RemoteCatalogDownloader(this, this, (String) null); - - // override with env variables catalog entries: - envParameters.put("GRAALVM_COMPONENT_CATALOG_1_URL", "test://graalv.org/test/envcatalog.properties"); - envParameters.put("GRAALVM_COMPONENT_CATALOG_1_LABEL", "First env"); - - List sources = d.readChannelSources(); - assertEquals(1, sources.size()); - assertTrue(sources.get(0).getLocationURL().endsWith("envcatalog.properties")); - } - - public static List callReadChannelSources(RemoteCatalogDownloader d) { - return d.readChannelSources(); - } -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteStorageTest.java b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteStorageTest.java deleted file mode 100644 index 6a733436ef28..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/RemoteStorageTest.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.TestBase; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.commands.MockStorage; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -public class RemoteStorageTest extends TestBase { - private static final String TEST_GRAAL_FLAVOUR = "linux_amd64"; - private static final String TEST_BASE_URL_DIR = "https://graalvm.io/"; - private static final String TEST_BASE_URL = TEST_BASE_URL_DIR + "download/catalog"; - private RemotePropertiesStorage remStorage; - private MockStorage storage; - private ComponentRegistry localRegistry; - private Properties catalogProps = new Properties(); - - private String graalVersion = "0.33-dev"; - private String graalSelector = TEST_GRAAL_FLAVOUR; - - @Rule public ExpectedException exception = ExpectedException.none(); - - @Before - public void setUp() throws Exception { - storage = new MockStorage(); - remStorage = new RemotePropertiesStorage(this, localRegistry, catalogProps, graalSelector, - Version.fromString(graalVersion), SystemUtils.toURL(TEST_BASE_URL)); - try (InputStream is = getClass().getResourceAsStream("catalog.properties")) { - catalogProps.load(is); - } - } - - private void loadCatalog(String s) throws IOException { - catalogProps.clear(); - localRegistry = new ComponentRegistry(this, storage); - try (InputStream is = getClass().getResourceAsStream(s)) { - catalogProps.load(is); - } - } - - private void forceLoadCatalog(String s) throws IOException { - loadCatalog(s); - remStorage = new RemotePropertiesStorage(this, localRegistry, catalogProps, graalSelector, - Version.fromString(graalVersion), SystemUtils.toURL(TEST_BASE_URL)); - } - - @Test - public void testListIDs() throws Exception { - Set ids = remStorage.listComponentIDs(); - - List l = new ArrayList<>(ids); - Collections.sort(l); - - assertEquals(Arrays.asList("r", "ruby"), l); - } - - private ComponentInfo loadLastComponent(String id) throws IOException { - Set infos = remStorage.loadComponentMetadata(id); - if (infos == null || infos.isEmpty()) { - return null; - } - List sorted = new ArrayList<>(infos); - Collections.sort(sorted, ComponentInfo.versionComparator()); - return sorted.get(sorted.size() - 1); - } - - @Test - public void testLoadMetadata() throws Exception { - ComponentInfo rInfo = loadLastComponent("r"); - assertEquals("FastR 0.33-dev", rInfo.getName()); - assertEquals("R", rInfo.getId()); - } - - @Test - public void testRelativeRemoteURL() throws Exception { - ComponentInfo rInfo = loadLastComponent("r"); - assertEquals(SystemUtils.toURL(TEST_BASE_URL_DIR + "0.33-dev/graalvm-fastr.zip"), rInfo.getRemoteURL()); - } - - @Test - public void testInvalidRemoteURL() throws Exception { - loadCatalog("catalog.bad1.properties"); - // load good compoennt: - ComponentInfo rInfo = loadLastComponent("ruby"); - assertEquals("ruby", rInfo.getId()); - - // and now bad component - exception.expect(MalformedURLException.class); - rInfo = loadLastComponent("r"); - } - - @Test - public void testLoadMetadataMalformed() throws Exception { - loadCatalog("catalog.bad2.properties"); - // load good compoennt: - ComponentInfo rInfo = loadLastComponent("r"); - assertEquals("R", rInfo.getId()); - - // and now bad component - exception.expect(MetadataException.class); - exception.expectMessage("ERROR_InvalidVersion"); - rInfo = loadLastComponent("ruby"); - } - - static byte[] truffleruby2Hash = { - (byte) 0xae, - (byte) 0xd6, - 0x7c, - 0x4d, - 0x3c, - 0x04, - 0x01, - 0x15, - 0x13, - (byte) 0xf8, - (byte) 0x94, - 0x0b, - (byte) 0xf6, - (byte) 0xe6, - (byte) 0xea, - 0x22, - 0x5d, - 0x34, - 0x5c, - 0x27, - (byte) 0xa1, - (byte) 0xa3, - (byte) 0xcd, - (byte) 0xe4, - (byte) 0xdd, - 0x0c, - 0x46, - 0x36, - 0x45, - 0x3f, - 0x42, - (byte) 0xba - }; - - static String truffleruby2HashString = "aed67c4d3c04011513f8940bf6e6ea225d345c27a1a3cde4dd0c4636453f42ba"; - static String truffleruby2HashString2 = "ae:d6:7c:4d:3c:04:01:15:13:f8:94:0b:f6:e6:ea:22:5d:34:5c:27:a1:a3:cd:e4:dd:0c:46:36:45:3f:42:ba"; - - @Test - public void testHashString() throws Exception { - byte[] bytes = SystemUtils.toHashBytes(truffleruby2HashString); - assertArrayEquals(truffleruby2Hash, bytes); - } - - @Test - public void testHashStringDivided() throws Exception { - byte[] bytes = SystemUtils.toHashBytes(truffleruby2HashString2); - assertArrayEquals(truffleruby2Hash, bytes); - } - - /** - * Checks that multi-version properties load without error. - */ - @Test - public void loadMultipleVersions() throws Exception { - loadCatalog("catalogMultiVersions.properties"); - Set ids = remStorage.listComponentIDs(); - assertEquals(3, ids.size()); - assertTrue(ids.contains("python")); - } - - /** - * Checks that versions prior the graalvm version are not included. - */ - @Test - public void obsoleteVersionsNotIncluded() throws Exception { - loadCatalog("catalogMultiVersions.properties"); - remStorage = new RemotePropertiesStorage(this, localRegistry, catalogProps, TEST_GRAAL_FLAVOUR, - Version.fromString("1.0.0.0"), SystemUtils.toURL(TEST_BASE_URL)); - Set rubies = remStorage.loadComponentMetadata("ruby"); - // 1.0.0.0 and 1.0.1.0 versions - assertEquals(2, rubies.size()); - - Set rs = remStorage.loadComponentMetadata("r"); - assertEquals(1, rs.size()); - - Set pythons = remStorage.loadComponentMetadata("python"); - assertEquals(1, pythons.size()); - } - - @Test - public void checkMultipleGraalVMDependencies() throws Exception { - loadCatalog("catalogMultiVersions.properties"); - - Set rubies = remStorage.loadComponentMetadata("ruby"); - Set versions = new HashSet<>(); - for (ComponentInfo ci : rubies) { - Version compVersion = ci.getVersion(); - assertTrue(versions.add(compVersion)); - - String gv = ci.getRequiredGraalValues().get(BundleConstants.GRAAL_VERSION); - assertEquals(gv, compVersion.toString()); - } - } - - @Test - public void loadMultipleComponentFlavours() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "1.0.0.0"); - loadCatalog("catalogMultiFlavours.properties"); - Set ids = remStorage.listComponentIDs(); - assertEquals(3, ids.size()); - assertTrue(ids.contains("python")); - List infos = new ArrayList<>(remStorage.loadComponentMetadata("ruby")); - assertEquals(4, infos.size()); - - Collections.sort(infos, (a, b) -> compare( - a.getRequiredGraalValues().get(CommonConstants.CAP_JAVA_VERSION), - b.getRequiredGraalValues().get(CommonConstants.CAP_JAVA_VERSION))); - ComponentInfo ci; - - ci = infos.get(2); - assertEquals("ruby", ci.getId()); - assertEquals("11", ci.getRequiredGraalValues().get(CommonConstants.CAP_JAVA_VERSION)); - - ci = infos.get(3); - assertEquals("ruby", ci.getId()); - assertEquals("8", ci.getRequiredGraalValues().get(CommonConstants.CAP_JAVA_VERSION)); - - } - - private void setSelector(String os, String variant, String arch) { - String s = SystemUtils.patternOsName(os, variant) + "_" + SystemUtils.patternOsArch(arch); - graalSelector = s; - } - - private void assertComponentHasNormalizedValues(String cid) throws IOException { - Set infos = remStorage.loadComponentMetadata(cid); - assertEquals(1, infos.size()); - ComponentInfo ci = infos.iterator().next(); - - String os = ci.getRequiredGraalValues().get(CommonConstants.CAP_OS_NAME); - String arch = ci.getRequiredGraalValues().get(CommonConstants.CAP_OS_ARCH); - - String nos = SystemUtils.normalizeOSName(os, arch); - String narch = SystemUtils.normalizeArchitecture(os, arch); - - assertEquals(nos, os); - assertEquals(narch, arch); - } - - private void assertAllComponentsLoaded() throws IOException { - Set ids = remStorage.listComponentIDs(); - assertEquals(2, ids.size()); - assertTrue(ids.contains("ruby")); - assertTrue(ids.contains("r")); - - // assertComponentHasNormalizedValues("ruby"); - assertComponentHasNormalizedValues("r"); - } - - @Test - public void testMixedLinuxArchitetures() throws Exception { - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.33-dev"); - // selector is opposite to what's in the catalog file. - setSelector("linux", null, "x86_64"); - forceLoadCatalog("catalogWithDifferentOsArch.properties"); - assertAllComponentsLoaded(); - - setSelector("linux", "musl", "x86_64"); - forceLoadCatalog("catalogWithDifferentOsArch.properties"); - assertAllComponentsLoaded(); - - graalVersion = "0.34-dev"; - setSelector("Linux", null, "amd64"); - forceLoadCatalog("catalogWithDifferentOsArch.properties"); - assertAllComponentsLoaded(); - - setSelector("Linux", "musl", "amd64"); - forceLoadCatalog("catalogWithDifferentOsArch.properties"); - assertAllComponentsLoaded(); - - graalVersion = "0.35-dev"; - setSelector("Darwin", null, "amd64"); - forceLoadCatalog("catalogWithDifferentOsArch.properties"); - assertAllComponentsLoaded(); - - storage.graalInfo.put(CommonConstants.CAP_GRAALVM_VERSION, "0.35-dev"); - setSelector("macos", null, "x86_64"); - forceLoadCatalog("catalogWithDifferentOsArch.properties"); - assertAllComponentsLoaded(); - } - - static int compare(String a, String b) { - if (a == b) { - return 0; - } - if (a == null) { - return -1; - } else if (b == null) { - return 1; - } - return a.compareTo(b); - } - -} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad1.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad1.properties deleted file mode 100644 index e28e368d5cb0..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad1.properties +++ /dev/null @@ -1,11 +0,0 @@ -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: foo://&graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad2.properties deleted file mode 100644 index abc66b8d1a02..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.bad2.properties +++ /dev/null @@ -1,11 +0,0 @@ -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33##-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)/(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.properties deleted file mode 100644 index 588be2b81a80..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalog.properties +++ /dev/null @@ -1,12 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogCorrupted.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogCorrupted.properties deleted file mode 100644 index b7af51e27f82..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogCorrupted.properties +++ /dev/null @@ -1,12 +0,0 @@ -Component.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: \uxxxx graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat1.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat1.properties deleted file mode 100644 index 20c841fae388..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat1.properties +++ /dev/null @@ -1,91 +0,0 @@ -org.graalvm.1.0.0-rc15_linux_amd64=GraalVM 1.0.0-rc15 linux/amd64 -org.graalvm.1.0.0-rc15_macos_amd64=GraalVM 1.0.0-rc15 macos/amd64 - -Component.1.0.0-rc15_linux_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0-rc15/python-linux-amd64.jar -Component.1.0.0-rc15_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0-rc15_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc15)(os_name=linux)(os_arch=amd64))" -Component.1.0.0-rc15_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0-rc15_linux_amd64.org.graalvm.python-Bundle-Version=1.0.0-rc15 -Component.1.0.0-rc15_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0-rc15_macos_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0-rc15/python-macos-amd64.jar -Component.1.0.0-rc15_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0-rc15_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc15)(os_name=macos)(os_arch=amd64))" -Component.1.0.0-rc15_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0-rc15_macos_amd64.org.graalvm.python-Bundle-Version=1.0.0-rc15 -Component.1.0.0-rc15_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0-rc15_linux_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0-rc15/r-linux-amd64.jar -Component.1.0.0-rc15_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0-rc15_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc15)(os_name=linux)(os_arch=amd64))" -Component.1.0.0-rc15_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0-rc15_linux_amd64.org.graalvm.r-Bundle-Version=1.0.0-rc15 -Component.1.0.0-rc15_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0-rc15_macos_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0-rc15/r-macos-amd64.jar -Component.1.0.0-rc15_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0-rc15_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc15)(os_name=macos)(os_arch=amd64))" -Component.1.0.0-rc15_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0-rc15_macos_amd64.org.graalvm.r-Bundle-Version=1.0.0-rc15 -Component.1.0.0-rc15_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0-rc15_linux_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0-rc15/ruby-linux-amd64.jar -Component.1.0.0-rc15_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0-rc15_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc15)(os_name=linux)(os_arch=amd64))" -Component.1.0.0-rc15_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0-rc15_linux_amd64.org.graalvm.ruby-Bundle-Version=1.0.0-rc15 -Component.1.0.0-rc15_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.1.0.0-rc15_macos_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0-rc15/ruby-macos-amd64.jar -Component.1.0.0-rc15_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0-rc15_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0-rc15)(os_name=macos)(os_arch=amd64))" -Component.1.0.0-rc15_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0-rc15_macos_amd64.org.graalvm.ruby-Bundle-Version=1.0.0-rc15 -Component.1.0.0-rc15_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - - -org.graalvm.1.0.0_linux_amd64=GraalVM 1.0.0 linux/amd64 -org.graalvm.1.0.0_macos_amd64=GraalVM 1.0.0 macos/amd64 - -Component.1.0.0_linux_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_macos_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_linux_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_macos_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_linux_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.1.0.0_macos_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat2.properties deleted file mode 100644 index 4f02f24face3..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormat2.properties +++ /dev/null @@ -1,90 +0,0 @@ -org.graalvm.1.0.0_linux_amd64=GraalVM 1.0.0 linux/amd64 -org.graalvm.1.0.0_macos_amd64=GraalVM 1.0.0 macos/amd64 - -Component.1.0.0_linux_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_macos_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_linux_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_macos_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_linux_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.1.0.0_macos_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -org.graalvm.1.0.0_linux_amd64=GraalVM 1.0.0 linux/amd64 -org.graalvm.1.0.0_macos_amd64=GraalVM 1.0.0 macos/amd64 - -Component.1.0.0_linux_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_macos_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_linux_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_macos_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_linux_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.1.0.0_macos_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormatMix.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormatMix.properties deleted file mode 100644 index db7fbdfa13e5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogFormatMix.properties +++ /dev/null @@ -1,135 +0,0 @@ -org.graalvm.1.0.0_linux_amd64=GraalVM 1.0.0 linux/amd64 -org.graalvm.1.0.0_macos_amd64=GraalVM 1.0.0 macos/amd64 - -Component.1.0.0_linux_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_linux_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_macos_amd64.org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.0/python-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Name=Graal.Python -Component.1.0.0_macos_amd64.org.graalvm.python-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.1.0.0_linux_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_linux_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_macos_amd64.org.graalvm.r=https://acme.org/graalvm/fastr/1.0.0/r-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Name=FastR -Component.1.0.0_macos_amd64.org.graalvm.r-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.1.0.0_linux_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-linux-amd64.jar -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=linux)(os_arch=amd64))" -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_linux_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_linux_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.1.0.0_macos_amd64.org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.0/ruby-macos-amd64.jar -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0)(os_name=macos)(os_arch=amd64))" -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.1.0.0_macos_amd64.org.graalvm.ruby-Bundle-Version=1.0.0 -Component.1.0.0_macos_amd64.org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -org.graalvm.linux_amd64/1.0.1.0=GraalVM 1.0.1.0 linux/amd64 -org.graalvm.macos_amd64/1.0.1.0=GraalVM 1.0.1.0 macos/amd64 - -Component.linux_amd64/1.0.1.0/org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.1.0/python-linux-amd64.jar -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.macos_amd64/1.0.1.0/org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.1.0/python-macos-amd64.jar -Component.macos_amd64/1.0.1.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.macos_amd64/1.0.1.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=macos)(os_arch=amd64))" -Component.macos_amd64/1.0.1.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.macos_amd64/1.0.1.0/org.graalvm.python-Bundle-Version=1.0.1.0 -Component.macos_amd64/1.0.1.0/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.linux_amd64/1.0.1.0/org.graalvm.r=https://acme.org/graalvm/fastr/1.0.1.0/r-linux-amd64.jar -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.macos_amd64/1.0.1.0/org.graalvm.r=https://acme.org/graalvm/fastr/1.0.1.0/r-macos-amd64.jar -Component.macos_amd64/1.0.1.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.macos_amd64/1.0.1.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=macos)(os_arch=amd64))" -Component.macos_amd64/1.0.1.0/org.graalvm.r-Bundle-Name=FastR -Component.macos_amd64/1.0.1.0/org.graalvm.r-Bundle-Version=1.0.1.0 -Component.macos_amd64/1.0.1.0/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.linux_amd64/1.0.1.0/org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.1.0/ruby-linux-amd64.jar -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.macos_amd64/1.0.1.0/org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.1.0/ruby-macos-amd64.jar -Component.macos_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.macos_amd64/1.0.1.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=macos)(os_arch=amd64))" -Component.macos_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.macos_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Version=1.0.1.0 -Component.macos_amd64/1.0.1.0/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -org.graalvm.linux_amd64/1.0.2.0-1=GraalVM 1.0.2.0-1 linux/amd64 -org.graalvm.macos_amd64/1.0.2.0-1=GraalVM 1.0.2.0-1 macos/amd64 - -Component.linux_amd64/1.0.2.0-1/org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.2.0-1/python-linux-amd64.jar -Component.linux_amd64/1.0.2.0-1/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.2.0-1/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.2.0-1)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.2.0-1/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.2.0-1/org.graalvm.python-Bundle-Version=1.0.2.0-1 -Component.linux_amd64/1.0.2.0-1/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.macos_amd64/1.0.2.0-1/org.graalvm.python=https://acme.org/graalvm/graalpython/1.0.2.0-1/python-macos-amd64.jar -Component.macos_amd64/1.0.2.0-1/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.macos_amd64/1.0.2.0-1/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.2.0-1)(os_name=macos)(os_arch=amd64))" -Component.macos_amd64/1.0.2.0-1/org.graalvm.python-Bundle-Name=Graal.Python -Component.macos_amd64/1.0.2.0-1/org.graalvm.python-Bundle-Version=1.0.2.0-1 -Component.macos_amd64/1.0.2.0-1/org.graalvm.python-x-GraalVM-Working-Directories=jre/languages/python - -Component.linux_amd64/1.0.2.0-1/org.graalvm.r=https://acme.org/graalvm/fastr/1.0.2.0-1/r-linux-amd64.jar -Component.linux_amd64/1.0.2.0-1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.2.0-1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.2.0-1)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.2.0-1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.2.0-1/org.graalvm.r-Bundle-Version=1.0.2.0-1 -Component.linux_amd64/1.0.2.0-1/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.macos_amd64/1.0.2.0-1/org.graalvm.r=https://acme.org/graalvm/fastr/1.0.2.0-1/r-macos-amd64.jar -Component.macos_amd64/1.0.2.0-1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.macos_amd64/1.0.2.0-1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.2.0-1)(os_name=macos)(os_arch=amd64))" -Component.macos_amd64/1.0.2.0-1/org.graalvm.r-Bundle-Name=FastR -Component.macos_amd64/1.0.2.0-1/org.graalvm.r-Bundle-Version=1.0.2.0-1 -Component.macos_amd64/1.0.2.0-1/org.graalvm.r-x-GraalVM-Working-Directories=jre/languages/R - -Component.linux_amd64/1.0.2.0-1/org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.2.0-1/ruby-linux-amd64.jar -Component.linux_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.2.0-1)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-Version=1.0.2.0-1 -Component.linux_amd64/1.0.2.0-1/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - -Component.macos_amd64/1.0.2.0-1/org.graalvm.ruby=https://acme.org/graalvm/truffleruby/1.0.2.0-1/ruby-macos-amd64.jar -Component.macos_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.macos_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.2.0-1)(os_name=macos)(os_arch=amd64))" -Component.macos_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.macos_amd64/1.0.2.0-1/org.graalvm.ruby-Bundle-Version=1.0.2.0-1 -Component.macos_amd64/1.0.2.0-1/org.graalvm.ruby-x-GraalVM-Working-Directories=jre/languages/ruby - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiFlavours.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiFlavours.properties deleted file mode 100644 index 6d87be728ad4..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiFlavours.properties +++ /dev/null @@ -1,52 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - - -org.graalvm.linux_amd64/1.0.0.0: GraalVM 1.0 -Component.linux_amd64/1.0.0.0/cafebabe/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/cafebabe/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(java_version=8)(os_arch=amd64))" - -Component.linux_amd64/1.0.0.0/deadbeef/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/deadbeef/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(java_version=11)(os_arch=amd64))" - -Component.linux_amd64/1.0.0.0/cafebabe/r: ../1.0.0.0/graalvm-fastr.zip -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-Name: FastR -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-Symbolic-Name: R -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/cafebabe/r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - -org.graalvm.linux_amd64/1.0.1.0: GraalVM 1.0.1 -Component.linux_amd64/1.0.1.0/cafebabe/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/cafebabe/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - - -# Python is intentionally just for version 1.0.1.0 -Component.linux_amd64/1.0.1.0/cafebabe/python: graalvm-python.zip -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-Symbolic-Name: python -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/cafebabe/python-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1.properties deleted file mode 100644 index a44f2dde80a5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1.properties +++ /dev/null @@ -1,17 +0,0 @@ -org.graalvm.linux_amd64/1.0.1.0: GraalVM 1.0.1 -Component.linux_amd64/1.0.1.0/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.1.0/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.1.0/ruby-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - - -# Python is intentionally just for version 1.0.1.0 -Component.linux_amd64/1.0.1.0/python: graalvm-python.zip -Component.linux_amd64/1.0.1.0/python-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/python-Bundle-Symbolic-Name: python -Component.linux_amd64/1.0.1.0/python-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/python-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1Mergeable.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1Mergeable.properties deleted file mode 100644 index 7c6e10b0b652..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart1Mergeable.properties +++ /dev/null @@ -1,18 +0,0 @@ -org.graalvm.linux_amd64/1.0.0.0: GraalVM 1.0 -org.graalvm.linux_amd64/1.0.1.0: GraalVM 1.0.1 -Component.linux_amd64/1.0.1.0/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.1.0/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.1.0/ruby-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - - -# Python is intentionally just for version 1.0.1.0 -Component.linux_amd64/1.0.1.0/python: graalvm-python.zip -Component.linux_amd64/1.0.1.0/python-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/python-Bundle-Symbolic-Name: python -Component.linux_amd64/1.0.1.0/python-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/python-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart2.properties deleted file mode 100644 index 09d69d5d9799..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart2.properties +++ /dev/null @@ -1,13 +0,0 @@ -org.graalvm.linux_amd64/1.0.0.0: GraalVM 1.0 -Component.linux_amd64/1.0.0.0/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.0.0/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.0.0/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.0.0/ruby-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/r: ../1.0.0.0/graalvm-fastr.zip -Component.linux_amd64/1.0.0.0/r-Bundle-Name: FastR -Component.linux_amd64/1.0.0.0/r-Bundle-Symbolic-Name: R -Component.linux_amd64/1.0.0.0/r-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart3.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart3.properties deleted file mode 100644 index 922636f4c231..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiPart3.properties +++ /dev/null @@ -1,8 +0,0 @@ -org.graalvm.linux_amd64/1.0.1.0: GraalVM 1.0.1 -Component.linux_amd64/1.0.1.0/r: graalvm-ruby.zip -Component.linux_amd64/1.0.1.0/r-Bundle-Name: FastR -Component.linux_amd64/1.0.1.0/r-Bundle-Symbolic-Name: r -Component.linux_amd64/1.0.1.0/r-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/r-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiVersions.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiVersions.properties deleted file mode 100644 index 14b4eb559395..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogMultiVersions.properties +++ /dev/null @@ -1,44 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" -Component.0.33-dev_linux_amd64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_linux_amd64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_linux_amd64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - - -org.graalvm.linux_amd64/1.0.0.0: GraalVM 1.0 -Component.linux_amd64/1.0.0.0/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.0.0/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.0.0/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.0.0/ruby-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/r: ../1.0.0.0/graalvm-fastr.zip -Component.linux_amd64/1.0.0.0/r-Bundle-Name: FastR -Component.linux_amd64/1.0.0.0/r-Bundle-Symbolic-Name: R -Component.linux_amd64/1.0.0.0/r-Bundle-Version: 1.0.0.0 -Component.linux_amd64/1.0.0.0/r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - -org.graalvm.linux_amd64/1.0.1.0: GraalVM 1.0.1 -Component.linux_amd64/1.0.1.0/ruby: graalvm-ruby.zip -Component.linux_amd64/1.0.1.0/ruby-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/ruby-Bundle-Symbolic-Name: ruby -Component.linux_amd64/1.0.1.0/ruby-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - - -# Python is intentionally just for version 1.0.1.0 -Component.linux_amd64/1.0.1.0/python: graalvm-python.zip -Component.linux_amd64/1.0.1.0/python-Bundle-Name: TruffleRuby -Component.linux_amd64/1.0.1.0/python-Bundle-Symbolic-Name: python -Component.linux_amd64/1.0.1.0/python-Bundle-Version: 1.0.1.0 -Component.linux_amd64/1.0.1.0/python-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogWithDifferentOsArch.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogWithDifferentOsArch.properties deleted file mode 100644 index 26c95924064c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/catalogWithDifferentOsArch.properties +++ /dev/null @@ -1,75 +0,0 @@ -org.graalvm.0.33-dev_linux_amd64: GraalVM 0.33-dev linux amd64 -org.graalvm.0.33-dev_linux_musl_amd64: GraalVM 0.33-dev linux_musl amd64 - -Component.0.33-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.33-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_arch=amd64))" - -Component.0.33-dev_Linux_x86_64.r: ../0.33-dev/graalvm-fastr.zip -Component.0.33-dev_Linux_x86_64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_Linux_x86_64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_Linux_x86_64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_Linux_x86_64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.33-dev)(os_name=Linux)(os_arch=x86_64))" - -Component.0.33-dev_linux_musl_amd64.ruby: graalvm-ruby_musl.zip -Component.0.33-dev_linux_musl_amd64.ruby-Bundle-Name: TruffleRuby 0.33-dev -Component.0.33-dev_linux_musl_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.33-dev_linux_musl_amd64.ruby-Bundle-Version: 0.33-dev -Component.0.33-dev_linux_musl_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=linux)(os_variant=musl)(os_arch=amd64))" - -Component.0.33-dev_Linux_musl_x86_64.r: ../0.33-dev/graalvm-fastr_musl.zip -Component.0.33-dev_Linux_musl_x86_64.r-Bundle-Name: FastR 0.33-dev -Component.0.33-dev_Linux_musl_x86_64.r-Bundle-Symbolic-Name: R -Component.0.33-dev_Linux_musl_x86_64.r-Bundle-Version: 0.33-dev -Component.0.33-dev_Linux_musl_x86_64.r-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.33-dev)(os_name=Linux)(os_variant=musl)(os_arch=x86_64))" - -org.graalvm.0.34-dev_linux_x86_64: GraalVM 0.33-dev linux amd64 -org.graalvm.0.34-dev_linux_musl_x86_64: GraalVM 0.33-dev linux_musl amd64 - -Component.0.34-dev_linux_amd64.ruby: graalvm-ruby.zip -Component.0.34-dev_linux_amd64.ruby-Bundle-Name: TruffleRuby 0.34-dev -Component.0.34-dev_linux_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.34-dev_linux_amd64.ruby-Bundle-Version: 0.34-dev -Component.0.34-dev_linux_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.34-dev)(os_name=linux)(os_arch=amd64))" - -Component.0.34-dev_Linux_x86_64.r: ../0.34-dev/graalvm-fastr.zip -Component.0.34-dev_Linux_x86_64.r-Bundle-Name: FastR 0.34-dev -Component.0.34-dev_Linux_x86_64.r-Bundle-Symbolic-Name: R -Component.0.34-dev_Linux_x86_64.r-Bundle-Version: 0.34-dev -Component.0.34-dev_Linux_x86_64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.34-dev)(os_name=Linux)(os_arch=x86_64))" - -Component.0.34-dev_linux_musl_amd64.ruby: graalvm-ruby_musl.zip -Component.0.34-dev_linux_musl_amd64.ruby-Bundle-Name: TruffleRuby 0.34-dev -Component.0.34-dev_linux_musl_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.34-dev_linux_musl_amd64.ruby-Bundle-Version: 0.34-dev -Component.0.34-dev_linux_musl_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.34-dev)(os_name=linux)(os_variant=musl)(os_arch=amd64))" - -Component.0.34-dev_Linux_musl_x86_64.r: ../0.34-dev/graalvm-fastr_musl.zip -Component.0.34-dev_Linux_musl_x86_64.r-Bundle-Name: FastR 0.34-dev -Component.0.34-dev_Linux_musl_x86_64.r-Bundle-Symbolic-Name: R -Component.0.34-dev_Linux_musl_x86_64.r-Bundle-Version: 0.34-dev -Component.0.34-dev_Linux_musl_x86_64.r-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.34-dev)(os_name=Linux)(os_variant=musl)(os_arch=x86_64))" - -org.graalvm.0.35-dev_darwin_x86_64: GraalVM 0.33-dev linux amd64 - -Component.0.35-dev_darwin_amd64.ruby: graalvm-ruby.zip -Component.0.35-dev_darwin_amd64.ruby-Bundle-Name: TruffleRuby 0.35-dev -Component.0.35-dev_darwin_amd64.ruby-Bundle-Symbolic-Name: ruby -Component.0.35-dev_darwin_amd64.ruby-Bundle-Version: 0.35-dev -Component.0.35-dev_darwin_amd64.ruby-Bundle-RequireCapability: org.graalvm; \ - filter:="(&(graalvm_version=0.35-dev)(os_name=macos)(os_arch=amd64))" - -Component.0.35-dev_macos_x86_64.r: ../0.35-dev/graalvm-fastr.zip -Component.0.35-dev_macos_x86_64.r-Bundle-Name: FastR 0.35-dev -Component.0.35-dev_macos_x86_64.r-Bundle-Symbolic-Name: R -Component.0.35-dev_macos_x86_64.r-Bundle-Version: 0.35-dev -Component.0.35-dev_macos_x86_64.r-Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=0.35-dev)(os_name=Darwin)(os_arch=x86_64))" - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/emptyRelease.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/emptyRelease.properties deleted file mode 100644 index 8e3a9fba7023..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/emptyRelease.properties +++ /dev/null @@ -1,7 +0,0 @@ -JAVA_VERSION="1.8.0_272" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" jvmci:0bbce9bf3339 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438" -GRAALVM_VERSION="20.3.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ce.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ce.properties deleted file mode 100644 index f9943e9f7f3a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ce.properties +++ /dev/null @@ -1,8 +0,0 @@ -JAVA_VERSION="1.8.0_272" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" jvmci:0bbce9bf3339 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438" -GRAALVM_VERSION="20.3.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} -component_catalog="https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ceWithEE.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ceWithEE.properties deleted file mode 100644 index 48d97c77e218..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ceWithEE.properties +++ /dev/null @@ -1,8 +0,0 @@ -JAVA_VERSION="1.8.0_272" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" jvmci:0bbce9bf3339 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438" -GRAALVM_VERSION="20.3.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} -component_catalog="https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties|{ee=Enterprise Edition}gds://oca.opensource.oracle.com/gds/meta-data.json|https://www.graalvm.org/component-catalog/graal-updater-ee-component-catalog-java8.properties" diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ee.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ee.properties deleted file mode 100644 index 8a222a3e31f3..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release20ee.properties +++ /dev/null @@ -1,10 +0,0 @@ -JAVA_VERSION="1.8.0_271" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" .:37bcc83348f5 corba:628331de3f70 deploy:72af6e8518b4 hotspot/make/closed:ec4675b39294 hotspot/src/closed:ccf62e903c33 install:e88eaa33ef57 jaxp:c384762e3ead jaxws:42201112fc8a jdk:a72057a7a077 jdk/make/closed:fbbd4cb2442d jdk/src/closed:66ae2a776e8a langtools:56c7ccb7641f nashorn:2cde13247430 jvmci:6b5d53f096d8 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-enterprise:607aa8fb21145dd964ffddcad849f0534375166a graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm-enterprise:607aa8fb21145dd964ffddcad849f0534375166a substratevm-enterprise-gcs:d61eba18250db97ba247d31bd8b272fb681ca9f2 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong-managed:607aa8fb21145dd964ffddcad849f0534375166a tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools-enterprise:607aa8fb21145dd964ffddcad849f0534375166a truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm-enterprise:607aa8fb21145dd964ffddcad849f0534375166a" -BUILD_TYPE="commercial" -GRAALVM_VERSION="20.3.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-enterprise": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217785, "commit.rev": "607aa8fb21145dd964ffddcad849f0534375166a"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm-enterprise": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217785, "commit.rev": "607aa8fb21145dd964ffddcad849f0534375166a"}, "substratevm-enterprise-gcs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1603648394, "commit.rev": "d61eba18250db97ba247d31bd8b272fb681ca9f2"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong-managed": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217785, "commit.rev": "607aa8fb21145dd964ffddcad849f0534375166a"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools-enterprise": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217785, "commit.rev": "607aa8fb21145dd964ffddcad849f0534375166a"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm-enterprise": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217785, "commit.rev": "607aa8fb21145dd964ffddcad849f0534375166a"}} -component_catalog="gds://oca.opensource.oracle.com/gds/meta-data.json|uln://linux-update.oracle.com/rpc/api/?linux=generic_linux_x86_64_graalvm_jdk8&macos=macos_64_graalvm_jdk8&windows=windows_64_graalvm_jdk8|https://www.graalvm.org/component-catalog/graal-updater-ee-component-catalog-java8.properties" -ee_component_catalog_editionLabel=Enterprise Edition diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ce.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ce.properties deleted file mode 100644 index c6afe4aa3147..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ce.properties +++ /dev/null @@ -1,15 +0,0 @@ -JAVA_VERSION="1.8.0_272" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" jvmci:0bbce9bf3339 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438" -GRAALVM_VERSION="20.3.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} -component_catalog="https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties" - -component_catalog_url=https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties -component_catalog_label=GitHub CE 8 Components - -component_catalog_2_url=https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java11.properties -component_catalog_2_label=GitHub CE 11 Components - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ceWithEE.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ceWithEE.properties deleted file mode 100644 index 38556facba6c..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/release21ceWithEE.properties +++ /dev/null @@ -1,26 +0,0 @@ -JAVA_VERSION="1.8.0_272" -OS_NAME="Linux" -OS_VERSION="2.6" -OS_ARCH="amd64" -SOURCE=" jvmci:0bbce9bf3339 compiler:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 graal-js:b53c4e144b5909876b377e31be69e3b3f381ae0b graal-nodejs:b53c4e144b5909876b377e31be69e3b3f381ae0b java-benchmarks:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 regex:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sdk:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 substratevm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 sulong:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 tools:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 truffle:c5ff5a5a091bfd974640aaf6fbe51c81bd080438 vm:c5ff5a5a091bfd974640aaf6fbe51c81bd080438" -GRAALVM_VERSION="20.3.0" -COMMIT_INFO={"compiler": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "graal-js": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "graal-nodejs": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217687, "commit.rev": "b53c4e144b5909876b377e31be69e3b3f381ae0b"}, "java-benchmarks": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "regex": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sdk": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "substratevm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "sulong": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "tools": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "truffle": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}, "vm": {"commit.committer": "Gilles Duboscq ", "commit.committer-ts": 1605217754, "commit.rev": "c5ff5a5a091bfd974640aaf6fbe51c81bd080438"}} -component_catalog="https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties|{ee=Enterprise Edition}gds://oca.opensource.oracle.com/gds/meta-data.json|https://www.graalvm.org/component-catalog/graal-updater-ee-component-catalog-java8.properties" - -component_catalog_url=https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java8.properties -component_catalog_label=GitHub CE 8 Components -component_catalog_editionLabel=GraalVM CE - -component_catalog_2_url=https://www.graalvm.org/component-catalog/graal-updater-component-catalog-java11.properties -component_catalog_2_label=GitHub CE 11 Components - -ee_component_catalog_10_url=gds://oca.opensource.oracle.com/gds/meta-data.json -ee_component_catalog_10_label=GDS Component distribution -ee_component_catalog_editionLabel=GraalVM EE - -ee_component_catalog_15_url=https://whenever.acme.org/ee-extras.properties -ee_component_catalog_15_label=Some experimental components - -ee_component_catalog_13_url=https://www.graalvm.org/component-catalog/graal-updater-ee-component-catalog-java8.properties -ee_component_catalog_13_label=Github distribution -ee_component_catalog_13_paramX=valueY diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/truffleruby2.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/remote/data/truffleruby2.jar deleted file mode 100644 index 122291a96c5788ad041161df2adf63fa3eb26b28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180588 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%0DC@I+r}s!PmtJ?v={O@kPiR> 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 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/graalvm-19.3.0.0.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/graalvm-19.3.0.0.jar deleted file mode 100644 index f997a0c30bcf7d7d3b06cda75ea3f9b4d46fa7f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29450 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�oLVw%YF9vAF$UB)6n8A4y^X>ijsDbkd<*S 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. -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/llvm-toolchain/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/MANIFEST.MF deleted file mode 100644 index 210519336156..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/MANIFEST.MF +++ /dev/null @@ -1,25 +0,0 @@ -Bundle-Name: FastR -Bundle-Symbolic-Name: org.graalvm.R -Bundle-Version: 19.3.0.0 -Require-Bundle: org.graalvm.llvm-toolchain -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=19.3.0.0 - )(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/R -x-GraalVM-Message-PostInst: NOTES:\n---------------\nSome R packages nee - d a system-dependent configuration before they can be installed. A gener - ic configuration that works out of the box in most cases is provided by - default. If you wish to fine-tune the configuration to your system or sh - ould you encounter any issues during R package installation, try running - the following script that adjusts the configuration to your system: \n - ${graalvm_home}/jre/languages/R/bin/configure_fastr\n\nThe R componen - t comes without native image by default. If you wish to build the native - image, which provides faster startup, but slightly slower peak performa - nce, then run the following:\n ${graalvm_home}/jre/languages/R/bin/ins - tall_r_native_image\n\nThe native image is then used by default. Pass '- - -jvm' flag to the R or Rscript launcher to use JVM instead of the native - image. Note that the native image is not stable yet and is intended for - evaluation purposes and experiments. Some features may not work when th - e native image is installed, most notably the --polyglot switch. The nat - ive image can be uninstalled using the installation script with 'uninsta - ll' argument.\n\nSee http://www.graalvm.org/docs/reference-manual/langua - ges/r for more. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/permissions deleted file mode 100644 index 14fe1475669d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/permissions +++ /dev/null @@ -1,1622 +0,0 @@ -jre/languages/R/bin/R = rwxr-xr-x -jre/languages/R/bin/Rdconv = rwxr-xr-x -jre/languages/R/bin/SHLIB = rwxr-xr-x -jre/languages/R/bin/COMPILE = rwxr-xr-x -jre/languages/R/bin/LINK = rwxr-xr-x -jre/languages/R/bin/Sweave = rwxr-xr-x -jre/languages/R/bin/BATCH = rwxr-xr-x -jre/languages/R/bin/install_r_native_image = rwxr-xr-x -jre/languages/R/bin/f77_f2c = rwxr-xr-x -jre/languages/R/bin/build = rwxr-xr-x -jre/languages/R/bin/mkinstalldirs = rwxr-xr-x -jre/languages/R/bin/Rdiff = rwxr-xr-x -jre/languages/R/bin/check = rwxr-xr-x -jre/languages/R/bin/Stangle = rwxr-xr-x -jre/languages/R/bin/pager = rwxr-xr-x -jre/languages/R/include/S.h = rw-r--r-- -jre/languages/R/include/Rinternals.h = rw-r--r-- -jre/languages/R/include/Makefile = rw-r--r-- -jre/languages/R/include/Rembedded.h = rw-r--r-- -jre/languages/R/include/Rconfig.h = rw-r--r-- -jre/languages/R/include/Rdefines.h = rw-r--r-- -jre/languages/R/include/linked = rw-r--r-- -jre/languages/R/include/Rmath.h = rw-r--r-- -jre/languages/R/include/R.h = rw-r--r-- -jre/languages/R/include/Rversion.h = rw-r--r-- -jre/languages/R/include/Rinterface.h = rw-r--r-- -jre/languages/R/include/R_ext/GraphicsEngine.h = rw-r--r-- -jre/languages/R/include/R_ext/R-ftp-http.h = rw-r--r-- -jre/languages/R/include/R_ext/Error.h = rw-r--r-- -jre/languages/R/include/R_ext/Itermacros.h = rw-r--r-- -jre/languages/R/include/R_ext/Utils.h = rw-r--r-- -jre/languages/R/include/R_ext/stats_stubs.h = rw-r--r-- -jre/languages/R/include/R_ext/GetX11Image.h = rw-r--r-- -jre/languages/R/include/R_ext/GraphicsDevice.h = rw-r--r-- -jre/languages/R/include/R_ext/Callbacks.h = rw-r--r-- -jre/languages/R/include/R_ext/Rdynload.h = rw-r--r-- -jre/languages/R/include/R_ext/Parse.h = rw-r--r-- -jre/languages/R/include/R_ext/RS.h = rw-r--r-- -jre/languages/R/include/R_ext/BLAS.h = rw-r--r-- -jre/languages/R/include/R_ext/Arith.h = rw-r--r-- -jre/languages/R/include/R_ext/Boolean.h = rw-r--r-- -jre/languages/R/include/R_ext/Applic.h = rw-r--r-- -jre/languages/R/include/R_ext/Linpack.h = rw-r--r-- -jre/languages/R/include/R_ext/Constants.h = rw-r--r-- -jre/languages/R/include/R_ext/Riconv.h = rw-r--r-- -jre/languages/R/include/R_ext/RStartup.h = rw-r--r-- -jre/languages/R/include/R_ext/Print.h = rw-r--r-- -jre/languages/R/include/R_ext/QuartzDevice.h = rw-r--r-- -jre/languages/R/include/R_ext/libextern.h = rw-r--r-- -jre/languages/R/include/R_ext/MathThreads.h = rw-r--r-- -jre/languages/R/include/R_ext/Memory.h = rw-r--r-- -jre/languages/R/include/R_ext/Connections.h = rw-r--r-- -jre/languages/R/include/R_ext/PrtUtil.h = rw-r--r-- -jre/languages/R/include/R_ext/Altrep.h = rw-r--r-- -jre/languages/R/include/R_ext/Rallocators.h = rw-r--r-- -jre/languages/R/include/R_ext/Visibility.h = rw-r--r-- -jre/languages/R/include/R_ext/stats_package.h = rw-r--r-- -jre/languages/R/include/R_ext/Complex.h = rw-r--r-- -jre/languages/R/include/R_ext/Lapack.h = rw-r--r-- -jre/languages/R/include/R_ext/Random.h = rw-r--r-- -jre/languages/R/include/R_ext/eventloop.h = rw-r--r-- -jre/languages/R/lib/libgfortran.dylib = rwxrwxrwx -jre/languages/R/lib/libz.dylib = rwxrwxrwx -jre/languages/R/lib/libpcre.1.dylib = rw-r--r-- -jre/languages/R/lib/libRblas.dylib = rwxr-xr-x -jre/languages/R/lib/libpcre.dylib = rwxrwxrwx -jre/languages/R/lib/libgfortran.3.dylib = rw-r--r-- -jre/languages/R/lib/libgcc_s.dylib = rwxrwxrwx -jre/languages/R/lib/libR.dylib = rwxr-xr-x -jre/languages/R/lib/libquadmath.0.dylib = rw-r--r-- -jre/languages/R/lib/libz.1.dylib = rw-r--r-- -jre/languages/R/lib/libgcc_s.1.dylib = rw-r--r-- -jre/languages/R/lib/libRlapack.dylib = rwxr-xr-x -jre/languages/R/lib/libquadmath.dylib = rwxrwxrwx -jre/languages/R/library/MASS/CITATION = rw-r--r-- -jre/languages/R/library/MASS/NAMESPACE = rw-r--r-- -jre/languages/R/library/MASS/DESCRIPTION = rw-r--r-- -jre/languages/R/library/MASS/NEWS = rw-r--r-- -jre/languages/R/library/MASS/INDEX = rw-r--r-- -jre/languages/R/library/MASS/R/profiles.R = rw-r--r-- -jre/languages/R/library/MASS/R/write.matrix.R = rw-r--r-- -jre/languages/R/library/MASS/R/MASS.rdx = rw-r--r-- -jre/languages/R/library/MASS/R/corresp.R = rw-r--r-- -jre/languages/R/library/MASS/R/fitdistr.R = rw-r--r-- -jre/languages/R/library/MASS/R/sammon.R = rw-r--r-- -jre/languages/R/library/MASS/R/logtrans.R = rw-r--r-- -jre/languages/R/library/MASS/R/MASS = rw-r--r-- -jre/languages/R/library/MASS/R/MASS.rdb = rw-r--r-- -jre/languages/R/library/MASS/R/dose.p.R = rw-r--r-- -jre/languages/R/library/MASS/R/stdres.R = rw-r--r-- -jre/languages/R/library/MASS/R/enlist.R = rw-r--r-- -jre/languages/R/library/MASS/R/add.R = rw-r--r-- -jre/languages/R/library/MASS/R/neg.bin.R = rw-r--r-- -jre/languages/R/library/MASS/R/contr.sdif.R = rw-r--r-- -jre/languages/R/library/MASS/R/misc.R = rw-r--r-- -jre/languages/R/library/MASS/R/cov.trob.R = rw-r--r-- -jre/languages/R/library/MASS/R/polr.R = rw-r--r-- -jre/languages/R/library/MASS/R/hist.scott.R = rw-r--r-- -jre/languages/R/library/MASS/R/lda.R = rw-r--r-- -jre/languages/R/library/MASS/R/stepAIC.R = rw-r--r-- -jre/languages/R/library/MASS/R/area.R = rw-r--r-- -jre/languages/R/library/MASS/R/rms.curv.R = rw-r--r-- -jre/languages/R/library/MASS/R/fractions.R = rw-r--r-- -jre/languages/R/library/MASS/R/eqscplot.R = rw-r--r-- -jre/languages/R/library/MASS/R/kde2d.R = rw-r--r-- -jre/languages/R/library/MASS/R/lm.ridge.R = rw-r--r-- -jre/languages/R/library/MASS/R/confint.R = rw-r--r-- -jre/languages/R/library/MASS/R/ucv.R = rw-r--r-- -jre/languages/R/library/MASS/R/loglm.R = rw-r--r-- -jre/languages/R/library/MASS/R/gamma.shape.R = rw-r--r-- -jre/languages/R/library/MASS/R/negexp.R = rw-r--r-- -jre/languages/R/library/MASS/R/mca.R = rw-r--r-- -jre/languages/R/library/MASS/R/rlm.R = rw-r--r-- -jre/languages/R/library/MASS/R/truehist.R = rw-r--r-- -jre/languages/R/library/MASS/R/negbin.R = rw-r--r-- -jre/languages/R/library/MASS/R/qda.R = rw-r--r-- -jre/languages/R/library/MASS/R/huber.R = rw-r--r-- -jre/languages/R/library/MASS/R/mvrnorm.R = rw-r--r-- -jre/languages/R/library/MASS/R/zzz.R = rw-r--r-- -jre/languages/R/library/MASS/R/boxcox.R = rw-r--r-- -jre/languages/R/library/MASS/R/lm.gls.R = rw-r--r-- -jre/languages/R/library/MASS/R/parcoord.R = rw-r--r-- -jre/languages/R/library/MASS/R/glmmPQL.R = rw-r--r-- -jre/languages/R/library/MASS/R/isoMDS.R = rw-r--r-- -jre/languages/R/library/MASS/R/hubers.R = rw-r--r-- -jre/languages/R/library/MASS/R/lqs.R = rw-r--r-- -jre/languages/R/library/MASS/Meta/data.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/links.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/features.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/package.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/MASS/html/R.css = rw-r--r-- -jre/languages/R/library/MASS/html/00Index.html = rw-r--r-- -jre/languages/R/library/MASS/libs/MASS.so = rwxr-xr-x -jre/languages/R/library/MASS/po/pl/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/en@quot/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/de/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/ko/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/fr/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch13.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch07.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch09.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch03.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch10.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch14.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch04.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch11.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch15.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch05.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch01.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch12.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch16.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch06.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch02.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch08.R = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/MASS/help/MASS.rdx = rw-r--r-- -jre/languages/R/library/MASS/help/MASS.rdb = rw-r--r-- -jre/languages/R/library/MASS/help/AnIndex = rw-r--r-- -jre/languages/R/library/MASS/help/aliases.rds = rw-r--r-- -jre/languages/R/library/MASS/help/paths.rds = rw-r--r-- -jre/languages/R/library/cluster/CITATION = rw-r--r-- -jre/languages/R/library/cluster/NEWS.Rd = rw-r--r-- -jre/languages/R/library/cluster/NAMESPACE = rw-r--r-- -jre/languages/R/library/cluster/DESCRIPTION = rw-r--r-- -jre/languages/R/library/cluster/INDEX = rw-r--r-- -jre/languages/R/library/cluster/test-tools.R = rw-r--r-- -jre/languages/R/library/cluster/R/internal.R = rw-r--r-- -jre/languages/R/library/cluster/R/clusGapGen.R = rw-r--r-- -jre/languages/R/library/cluster/R/0aaa.R = rw-r--r-- -jre/languages/R/library/cluster/R/cluster.rdb = rw-r--r-- -jre/languages/R/library/cluster/R/cluster.rdx = rw-r--r-- -jre/languages/R/library/cluster/R/cluster = rw-r--r-- -jre/languages/R/library/cluster/R/coef.R = rw-r--r-- -jre/languages/R/library/cluster/R/clara.q = rw-r--r-- -jre/languages/R/library/cluster/R/silhouette.R = rw-r--r-- -jre/languages/R/library/cluster/R/mona.q = rw-r--r-- -jre/languages/R/library/cluster/R/pam.q = rw-r--r-- -jre/languages/R/library/cluster/R/plothier.q = rw-r--r-- -jre/languages/R/library/cluster/R/fanny.q = rw-r--r-- -jre/languages/R/library/cluster/R/plotpart.q = rw-r--r-- -jre/languages/R/library/cluster/R/daisy.q = rw-r--r-- -jre/languages/R/library/cluster/R/clusGap.R = rw-r--r-- -jre/languages/R/library/cluster/R/zzz.R = rw-r--r-- -jre/languages/R/library/cluster/R/ellipsoidhull.R = rw-r--r-- -jre/languages/R/library/cluster/R/diana.q = rw-r--r-- -jre/languages/R/library/cluster/R/agnes.q = rw-r--r-- -jre/languages/R/library/cluster/Meta/data.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/links.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/features.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/package.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/cluster/html/R.css = rw-r--r-- -jre/languages/R/library/cluster/html/00Index.html = rw-r--r-- -jre/languages/R/library/cluster/libs/cluster.so = rwxr-xr-x -jre/languages/R/library/cluster/po/pl/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/en@quot/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/en@quot/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/de/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/de/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/ko/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/ko/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/fr/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/cluster/help/cluster.rdb = rw-r--r-- -jre/languages/R/library/cluster/help/cluster.rdx = rw-r--r-- -jre/languages/R/library/cluster/help/AnIndex = rw-r--r-- -jre/languages/R/library/cluster/help/aliases.rds = rw-r--r-- -jre/languages/R/library/cluster/help/paths.rds = rw-r--r-- -jre/languages/R/library/parallel/NAMESPACE = rw-r--r-- -jre/languages/R/library/parallel/DESCRIPTION = rw-r--r-- -jre/languages/R/library/parallel/INDEX = rw-r--r-- -jre/languages/R/library/parallel/R/parallel = rw-r--r-- -jre/languages/R/library/parallel/R/parallel.rdx = rw-r--r-- -jre/languages/R/library/parallel/R/parallel.rdb = rw-r--r-- -jre/languages/R/library/parallel/Meta/links.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/features.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/package.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/parallel/html/R.css = rw-r--r-- -jre/languages/R/library/parallel/html/00Index.html = rw-r--r-- -jre/languages/R/library/parallel/libs/parallel.so = rwxr-xr-x -jre/languages/R/library/parallel/doc/parallel.pdf = rw-r--r-- -jre/languages/R/library/parallel/help/AnIndex = rw-r--r-- -jre/languages/R/library/parallel/help/aliases.rds = rw-r--r-- -jre/languages/R/library/parallel/help/paths.rds = rw-r--r-- -jre/languages/R/library/parallel/help/parallel.rdx = rw-r--r-- -jre/languages/R/library/parallel/help/parallel.rdb = rw-r--r-- -jre/languages/R/library/tools/NAMESPACE = rw-r--r-- -jre/languages/R/library/tools/DESCRIPTION = rw-r--r-- -jre/languages/R/library/tools/INDEX = rw-r--r-- -jre/languages/R/library/tools/R/tools = rw-r--r-- -jre/languages/R/library/tools/R/tools.rdb = rw-r--r-- -jre/languages/R/library/tools/R/tools.rdx = rw-r--r-- -jre/languages/R/library/tools/R/sysdata.rdb = rw-r--r-- -jre/languages/R/library/tools/R/sysdata.rdx = rw-r--r-- -jre/languages/R/library/tools/Meta/links.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/features.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/package.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/tools/html/R.css = rw-r--r-- -jre/languages/R/library/tools/html/00Index.html = rw-r--r-- -jre/languages/R/library/tools/libs/tools.so = rwxr-xr-x -jre/languages/R/library/tools/help/AnIndex = rw-r--r-- -jre/languages/R/library/tools/help/aliases.rds = rw-r--r-- -jre/languages/R/library/tools/help/tools.rdb = rw-r--r-- -jre/languages/R/library/tools/help/tools.rdx = rw-r--r-- -jre/languages/R/library/tools/help/paths.rds = rw-r--r-- -jre/languages/R/library/methods/NAMESPACE = rw-r--r-- -jre/languages/R/library/methods/DESCRIPTION = rw-r--r-- -jre/languages/R/library/methods/INDEX = rw-r--r-- -jre/languages/R/library/methods/R/methods = rw-r--r-- -jre/languages/R/library/methods/R/methods.rdx = rw-r--r-- -jre/languages/R/library/methods/R/methods.rdb = rw-r--r-- -jre/languages/R/library/methods/Meta/links.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/features.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/package.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/methods/html/R.css = rw-r--r-- -jre/languages/R/library/methods/html/00Index.html = rw-r--r-- -jre/languages/R/library/methods/libs/methods.so = rwxr-xr-x -jre/languages/R/library/methods/help/AnIndex = rw-r--r-- -jre/languages/R/library/methods/help/aliases.rds = rw-r--r-- -jre/languages/R/library/methods/help/paths.rds = rw-r--r-- -jre/languages/R/library/methods/help/methods.rdx = rw-r--r-- -jre/languages/R/library/methods/help/methods.rdb = rw-r--r-- -jre/languages/R/library/boot/CITATION = rw-r--r-- -jre/languages/R/library/boot/NAMESPACE = rw-r--r-- -jre/languages/R/library/boot/bd.q = rw-r--r-- -jre/languages/R/library/boot/DESCRIPTION = rw-r--r-- -jre/languages/R/library/boot/INDEX = rw-r--r-- -jre/languages/R/library/boot/R/bootfuns.q = rw-r--r-- -jre/languages/R/library/boot/R/boot = rw-r--r-- -jre/languages/R/library/boot/R/bootpracs.q = rw-r--r-- -jre/languages/R/library/boot/R/boot.rdb = rw-r--r-- -jre/languages/R/library/boot/R/boot.rdx = rw-r--r-- -jre/languages/R/library/boot/Meta/data.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/links.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/features.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/package.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/boot/html/R.css = rw-r--r-- -jre/languages/R/library/boot/html/00Index.html = rw-r--r-- -jre/languages/R/library/boot/po/pl/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/ru/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/en@quot/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/de/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/ko/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/fr/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/boot/help/AnIndex = rw-r--r-- -jre/languages/R/library/boot/help/aliases.rds = rw-r--r-- -jre/languages/R/library/boot/help/paths.rds = rw-r--r-- -jre/languages/R/library/boot/help/boot.rdb = rw-r--r-- -jre/languages/R/library/boot/help/boot.rdx = rw-r--r-- -jre/languages/R/library/datasets/NAMESPACE = rw-r--r-- -jre/languages/R/library/datasets/DESCRIPTION = rw-r--r-- -jre/languages/R/library/datasets/INDEX = rw-r--r-- -jre/languages/R/library/datasets/Meta/data.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/links.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/features.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/package.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/datasets/html/R.css = rw-r--r-- -jre/languages/R/library/datasets/html/00Index.html = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/datasets/data/morley.tab = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/datasets/help/AnIndex = rw-r--r-- -jre/languages/R/library/datasets/help/aliases.rds = rw-r--r-- -jre/languages/R/library/datasets/help/paths.rds = rw-r--r-- -jre/languages/R/library/datasets/help/datasets.rdx = rw-r--r-- -jre/languages/R/library/datasets/help/datasets.rdb = rw-r--r-- -jre/languages/R/library/nnet/CITATION = rw-r--r-- -jre/languages/R/library/nnet/NAMESPACE = rw-r--r-- -jre/languages/R/library/nnet/DESCRIPTION = rw-r--r-- -jre/languages/R/library/nnet/NEWS = rw-r--r-- -jre/languages/R/library/nnet/INDEX = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.R = rw-r--r-- -jre/languages/R/library/nnet/R/nnet = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.rdx = rw-r--r-- -jre/languages/R/library/nnet/R/zzz.R = rw-r--r-- -jre/languages/R/library/nnet/R/multinom.R = rw-r--r-- -jre/languages/R/library/nnet/R/vcovmultinom.R = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.rdb = rw-r--r-- -jre/languages/R/library/nnet/Meta/links.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/features.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/package.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/nnet/html/R.css = rw-r--r-- -jre/languages/R/library/nnet/html/00Index.html = rw-r--r-- -jre/languages/R/library/nnet/libs/nnet.so = rwxr-xr-x -jre/languages/R/library/nnet/po/pl/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/en@quot/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/de/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/ko/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/fr/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/help/AnIndex = rw-r--r-- -jre/languages/R/library/nnet/help/aliases.rds = rw-r--r-- -jre/languages/R/library/nnet/help/paths.rds = rw-r--r-- -jre/languages/R/library/nnet/help/nnet.rdx = rw-r--r-- -jre/languages/R/library/nnet/help/nnet.rdb = rw-r--r-- -jre/languages/R/library/utils/iconvlist = rw-r--r-- -jre/languages/R/library/utils/NAMESPACE = rw-r--r-- -jre/languages/R/library/utils/DESCRIPTION = rw-r--r-- -jre/languages/R/library/utils/INDEX = rw-r--r-- -jre/languages/R/library/utils/misc/exDIF.dif = rw-r--r-- -jre/languages/R/library/utils/misc/exDIF.csv = rw-r--r-- -jre/languages/R/library/utils/R/utils = rw-r--r-- -jre/languages/R/library/utils/R/sysdata.rdb = rw-r--r-- -jre/languages/R/library/utils/R/sysdata.rdx = rw-r--r-- -jre/languages/R/library/utils/R/utils.rdx = rw-r--r-- -jre/languages/R/library/utils/R/utils.rdb = rw-r--r-- -jre/languages/R/library/utils/Meta/links.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/features.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/package.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/utils/html/R.css = rw-r--r-- -jre/languages/R/library/utils/html/00Index.html = rw-r--r-- -jre/languages/R/library/utils/libs/utils.so = rwxr-xr-x -jre/languages/R/library/utils/Sweave/Sweave-test-1.Rnw = rw-r--r-- -jre/languages/R/library/utils/Sweave/example-1.Rnw = rw-r--r-- -jre/languages/R/library/utils/doc/Sweave.pdf = rw-r--r-- -jre/languages/R/library/utils/help/AnIndex = rw-r--r-- -jre/languages/R/library/utils/help/aliases.rds = rw-r--r-- -jre/languages/R/library/utils/help/paths.rds = rw-r--r-- -jre/languages/R/library/utils/help/utils.rdx = rw-r--r-- -jre/languages/R/library/utils/help/utils.rdb = rw-r--r-- -jre/languages/R/library/stats4/NAMESPACE = rw-r--r-- -jre/languages/R/library/stats4/DESCRIPTION = rw-r--r-- -jre/languages/R/library/stats4/INDEX = rw-r--r-- -jre/languages/R/library/stats4/R/stats4 = rw-r--r-- -jre/languages/R/library/stats4/R/stats4.rdx = rw-r--r-- -jre/languages/R/library/stats4/R/stats4.rdb = rw-r--r-- -jre/languages/R/library/stats4/Meta/links.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/features.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/package.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/stats4/html/R.css = rw-r--r-- -jre/languages/R/library/stats4/html/00Index.html = rw-r--r-- -jre/languages/R/library/stats4/help/AnIndex = rw-r--r-- -jre/languages/R/library/stats4/help/aliases.rds = rw-r--r-- -jre/languages/R/library/stats4/help/paths.rds = rw-r--r-- -jre/languages/R/library/stats4/help/stats4.rdx = rw-r--r-- -jre/languages/R/library/stats4/help/stats4.rdb = rw-r--r-- -jre/languages/R/library/rpart/NEWS.Rd = rw-r--r-- -jre/languages/R/library/rpart/NAMESPACE = rw-r--r-- -jre/languages/R/library/rpart/DESCRIPTION = rw-r--r-- -jre/languages/R/library/rpart/INDEX = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.exp.R = rw-r--r-- -jre/languages/R/library/rpart/R/predict.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.class.R = rw-r--r-- -jre/languages/R/library/rpart/R/post.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpartco.R = rw-r--r-- -jre/languages/R/library/rpart/R/plotcp.R = rw-r--r-- -jre/languages/R/library/rpart/R/path.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/prune.R = rw-r--r-- -jre/languages/R/library/rpart/R/labels.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/pred.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/xpred.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/na.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/snip.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.anova.R = rw-r--r-- -jre/languages/R/library/rpart/R/text.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.control.R = rw-r--r-- -jre/languages/R/library/rpart/R/printcp.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.poisson.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart = rw-r--r-- -jre/languages/R/library/rpart/R/rsq.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/formatg.R = rw-r--r-- -jre/languages/R/library/rpart/R/prune.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.branch.R = rw-r--r-- -jre/languages/R/library/rpart/R/roc.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/snip.rpart.mouse.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.rdx = rw-r--r-- -jre/languages/R/library/rpart/R/meanvar.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.rdb = rw-r--r-- -jre/languages/R/library/rpart/R/post.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/zzz.R = rw-r--r-- -jre/languages/R/library/rpart/R/summary.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpartcallback.R = rw-r--r-- -jre/languages/R/library/rpart/R/importance.R = rw-r--r-- -jre/languages/R/library/rpart/R/residuals.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.matrix.R = rw-r--r-- -jre/languages/R/library/rpart/R/model.frame.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/print.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/plot.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/data.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/links.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/features.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/package.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/rpart/html/R.css = rw-r--r-- -jre/languages/R/library/rpart/html/00Index.html = rw-r--r-- -jre/languages/R/library/rpart/libs/rpart.so = rwxr-xr-x -jre/languages/R/library/rpart/po/pl/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/pl/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ru/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ru/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/en@quot/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/en@quot/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/de/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/de/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ko/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ko/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/fr/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/fr/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/doc/index.html = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.R = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.Rnw = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.pdf = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.Rnw = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.pdf = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.R = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/rpart/help/AnIndex = rw-r--r-- -jre/languages/R/library/rpart/help/aliases.rds = rw-r--r-- -jre/languages/R/library/rpart/help/paths.rds = rw-r--r-- -jre/languages/R/library/rpart/help/rpart.rdx = rw-r--r-- -jre/languages/R/library/rpart/help/rpart.rdb = rw-r--r-- -jre/languages/R/library/lattice/CITATION = rw-r--r-- -jre/languages/R/library/lattice/NAMESPACE = rw-r--r-- -jre/languages/R/library/lattice/DESCRIPTION = rw-r--r-- -jre/languages/R/library/lattice/NEWS = rw-r--r-- -jre/languages/R/library/lattice/INDEX = rw-r--r-- -jre/languages/R/library/lattice/demo/intervals.R = rw-r--r-- -jre/languages/R/library/lattice/demo/panel.R = rw-r--r-- -jre/languages/R/library/lattice/demo/lattice.R = rw-r--r-- -jre/languages/R/library/lattice/demo/labels.R = rw-r--r-- -jre/languages/R/library/lattice/R/qq.R = rw-r--r-- -jre/languages/R/library/lattice/R/axis.R = rw-r--r-- -jre/languages/R/library/lattice/R/shingle.R = rw-r--r-- -jre/languages/R/library/lattice/R/settings.R = rw-r--r-- -jre/languages/R/library/lattice/R/summary.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/qqmath.R = rw-r--r-- -jre/languages/R/library/lattice/R/legend.R = rw-r--r-- -jre/languages/R/library/lattice/R/densityplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/panel.smoothscatter.R = rw-r--r-- -jre/languages/R/library/lattice/R/rfs.R = rw-r--r-- -jre/languages/R/library/lattice/R/interaction.R = rw-r--r-- -jre/languages/R/library/lattice/R/xyplot.ts.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice.rdb = rw-r--r-- -jre/languages/R/library/lattice/R/update.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/bwplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/cloud.R = rw-r--r-- -jre/languages/R/library/lattice/R/panel.superpose.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice.rdx = rw-r--r-- -jre/languages/R/library/lattice/R/panel.smooth.R = rw-r--r-- -jre/languages/R/library/lattice/R/levelplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice = rw-r--r-- -jre/languages/R/library/lattice/R/common.R = rw-r--r-- -jre/languages/R/library/lattice/R/panels.R = rw-r--r-- -jre/languages/R/library/lattice/R/layout.R = rw-r--r-- -jre/languages/R/library/lattice/R/miscellaneous.R = rw-r--r-- -jre/languages/R/library/lattice/R/make.groups.R = rw-r--r-- -jre/languages/R/library/lattice/R/histogram.R = rw-r--r-- -jre/languages/R/library/lattice/R/strip.R = rw-r--r-- -jre/languages/R/library/lattice/R/xyplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/scales.R = rw-r--r-- -jre/languages/R/library/lattice/R/zzz.R = rw-r--r-- -jre/languages/R/library/lattice/R/splom.R = rw-r--r-- -jre/languages/R/library/lattice/R/print.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/tmd.R = rw-r--r-- -jre/languages/R/library/lattice/R/parallel.R = rw-r--r-- -jre/languages/R/library/lattice/Meta/data.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/links.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/features.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/package.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/lattice/html/R.css = rw-r--r-- -jre/languages/R/library/lattice/html/00Index.html = rw-r--r-- -jre/languages/R/library/lattice/libs/lattice.so = rwxr-xr-x -jre/languages/R/library/lattice/po/pl/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/en@quot/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/de/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/ko/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/fr/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/lattice/help/AnIndex = rw-r--r-- -jre/languages/R/library/lattice/help/aliases.rds = rw-r--r-- -jre/languages/R/library/lattice/help/lattice.rdb = rw-r--r-- -jre/languages/R/library/lattice/help/lattice.rdx = rw-r--r-- -jre/languages/R/library/lattice/help/paths.rds = rw-r--r-- -jre/languages/R/library/nlme/CITATION = rw-r--r-- -jre/languages/R/library/nlme/NAMESPACE = rw-r--r-- -jre/languages/R/library/nlme/DESCRIPTION = rw-r--r-- -jre/languages/R/library/nlme/INDEX = rw-r--r-- -jre/languages/R/library/nlme/LICENCE = rw-r--r-- -jre/languages/R/library/nlme/mlbook/ch04.R = rw-r--r-- -jre/languages/R/library/nlme/mlbook/README = rw-r--r-- -jre/languages/R/library/nlme/mlbook/ch05.R = rw-r--r-- -jre/languages/R/library/nlme/R/gls.R = rw-r--r-- -jre/languages/R/library/nlme/R/simulate.R = rw-r--r-- -jre/languages/R/library/nlme/R/pdMat.R = rw-r--r-- -jre/languages/R/library/nlme/R/corStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/newFunc.R = rw-r--r-- -jre/languages/R/library/nlme/R/gnls.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.rdb = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.rdx = rw-r--r-- -jre/languages/R/library/nlme/R/VarCov.R = rw-r--r-- -jre/languages/R/library/nlme/R/lmList.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme = rw-r--r-- -jre/languages/R/library/nlme/R/reStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/newMethods.R = rw-r--r-- -jre/languages/R/library/nlme/R/zzMethods.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlsList.R = rw-r--r-- -jre/languages/R/library/nlme/R/VarCorr.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.R = rw-r--r-- -jre/languages/R/library/nlme/R/newGenerics.R = rw-r--r-- -jre/languages/R/library/nlme/R/lme.R = rw-r--r-- -jre/languages/R/library/nlme/R/varFunc.R = rw-r--r-- -jre/languages/R/library/nlme/R/modelStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/groupedData.R = rw-r--r-- -jre/languages/R/library/nlme/Meta/data.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/links.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/features.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/package.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/nlme/html/R.css = rw-r--r-- -jre/languages/R/library/nlme/html/00Index.html = rw-r--r-- -jre/languages/R/library/nlme/libs/nlme.so = rwxr-xr-x -jre/languages/R/library/nlme/po/pl/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/pl/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/en@quot/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/en@quot/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/de/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/de/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/ko/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/ko/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/fr/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/fr/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch03.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch04.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/runme.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/sims.rda = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch05.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch01.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch06.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch02.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch08.R = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/nlme/help/AnIndex = rw-r--r-- -jre/languages/R/library/nlme/help/aliases.rds = rw-r--r-- -jre/languages/R/library/nlme/help/nlme.rdb = rw-r--r-- -jre/languages/R/library/nlme/help/nlme.rdx = rw-r--r-- -jre/languages/R/library/nlme/help/paths.rds = rw-r--r-- -jre/languages/R/library/splines/NAMESPACE = rw-r--r-- -jre/languages/R/library/splines/DESCRIPTION = rw-r--r-- -jre/languages/R/library/splines/INDEX = rw-r--r-- -jre/languages/R/library/splines/R/splines = rw-r--r-- -jre/languages/R/library/splines/R/splines.rdb = rw-r--r-- -jre/languages/R/library/splines/R/splines.rdx = rw-r--r-- -jre/languages/R/library/splines/Meta/links.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/features.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/package.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/splines/html/R.css = rw-r--r-- -jre/languages/R/library/splines/html/00Index.html = rw-r--r-- -jre/languages/R/library/splines/libs/splines.so = rwxr-xr-x -jre/languages/R/library/splines/help/AnIndex = rw-r--r-- -jre/languages/R/library/splines/help/aliases.rds = rw-r--r-- -jre/languages/R/library/splines/help/paths.rds = rw-r--r-- -jre/languages/R/library/splines/help/splines.rdb = rw-r--r-- -jre/languages/R/library/splines/help/splines.rdx = rw-r--r-- -jre/languages/R/library/grDevices/NAMESPACE = rw-r--r-- -jre/languages/R/library/grDevices/DESCRIPTION = rw-r--r-- -jre/languages/R/library/grDevices/INDEX = rw-r--r-- -jre/languages/R/library/grDevices/demo/hclColors.R = rw-r--r-- -jre/languages/R/library/grDevices/demo/colors.R = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices.rdb = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices.rdx = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices = rw-r--r-- -jre/languages/R/library/grDevices/Meta/links.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/features.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/package.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/grDevices/html/R.css = rw-r--r-- -jre/languages/R/library/grDevices/html/00Index.html = rw-r--r-- -jre/languages/R/library/grDevices/icc/srgb = rw-r--r-- -jre/languages/R/library/grDevices/icc/srgb.flate = rw-r--r-- -jre/languages/R/library/grDevices/afm/cob_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvbo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvnbo___.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019064l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agd_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncb_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-Oblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/s050000l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkdi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/poi_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvno____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agw_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019043l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Roman.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvnb____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/sy______.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059013l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvo_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tii_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-Oblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncr_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010015l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Italic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/MustRead.html = rw-r--r-- -jre/languages/R/library/grDevices/afm/Symbol.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010033l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/com_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018015l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncbi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkd_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-BoldItalic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018032l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_regular_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059036l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/README = rw-r--r-- -jre/languages/R/library/grDevices/afm/cmti10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059033l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-Italic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agwo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvn_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-BoldOblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019063l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tibi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/coo_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/por_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agdo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_symbol_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ZapfDingbats.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/cobo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvb_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-BoldItalic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkli____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019044l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/pobi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tir_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018012l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkl_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/nci_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_boldx_italic_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hv______.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_italic_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059016l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/pob_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-BoldOblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010013l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/cmbxti10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tib_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018035l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_boldx_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010035l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/libs/grDevices.so = rwxr-xr-x -jre/languages/R/library/grDevices/enc/AdobeSym.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin7.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin2.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin1.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/Greek.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1257.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1250.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/TeXtext.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/PDFDoc.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1251.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1253.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/KOI8-U.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/Cyrillic.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/MacRoman.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/AdobeStd.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/KOI8-R.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin9.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/WinAnsi.enc = rw-r--r-- -jre/languages/R/library/grDevices/help/AnIndex = rw-r--r-- -jre/languages/R/library/grDevices/help/grDevices.rdb = rw-r--r-- -jre/languages/R/library/grDevices/help/grDevices.rdx = rw-r--r-- -jre/languages/R/library/grDevices/help/aliases.rds = rw-r--r-- -jre/languages/R/library/grDevices/help/paths.rds = rw-r--r-- -jre/languages/R/library/class/CITATION = rw-r--r-- -jre/languages/R/library/class/NAMESPACE = rw-r--r-- -jre/languages/R/library/class/DESCRIPTION = rw-r--r-- -jre/languages/R/library/class/NEWS = rw-r--r-- -jre/languages/R/library/class/INDEX = rw-r--r-- -jre/languages/R/library/class/R/class.rdb = rw-r--r-- -jre/languages/R/library/class/R/class.rdx = rw-r--r-- -jre/languages/R/library/class/R/multiedit.R = rw-r--r-- -jre/languages/R/library/class/R/SOM.R = rw-r--r-- -jre/languages/R/library/class/R/lvq.R = rw-r--r-- -jre/languages/R/library/class/R/class = rw-r--r-- -jre/languages/R/library/class/R/zzz.R = rw-r--r-- -jre/languages/R/library/class/R/knn.R = rw-r--r-- -jre/languages/R/library/class/Meta/links.rds = rw-r--r-- -jre/languages/R/library/class/Meta/features.rds = rw-r--r-- -jre/languages/R/library/class/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/class/Meta/package.rds = rw-r--r-- -jre/languages/R/library/class/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/class/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/class/html/R.css = rw-r--r-- -jre/languages/R/library/class/html/00Index.html = rw-r--r-- -jre/languages/R/library/class/libs/class.so = rwxr-xr-x -jre/languages/R/library/class/po/pl/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/en@quot/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/de/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/ko/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/fr/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/help/class.rdb = rw-r--r-- -jre/languages/R/library/class/help/class.rdx = rw-r--r-- -jre/languages/R/library/class/help/AnIndex = rw-r--r-- -jre/languages/R/library/class/help/aliases.rds = rw-r--r-- -jre/languages/R/library/class/help/paths.rds = rw-r--r-- -jre/languages/R/library/codetools/NAMESPACE = rw-r--r-- -jre/languages/R/library/codetools/DESCRIPTION = rw-r--r-- -jre/languages/R/library/codetools/INDEX = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.rdx = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.R = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.rdb = rw-r--r-- -jre/languages/R/library/codetools/R/codetools = rw-r--r-- -jre/languages/R/library/codetools/Meta/links.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/features.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/package.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/codetools/html/R.css = rw-r--r-- -jre/languages/R/library/codetools/html/00Index.html = rw-r--r-- -jre/languages/R/library/codetools/help/AnIndex = rw-r--r-- -jre/languages/R/library/codetools/help/codetools.rdx = rw-r--r-- -jre/languages/R/library/codetools/help/codetools.rdb = rw-r--r-- -jre/languages/R/library/codetools/help/aliases.rds = rw-r--r-- -jre/languages/R/library/codetools/help/paths.rds = rw-r--r-- -jre/languages/R/library/spatial/CITATION = rw-r--r-- -jre/languages/R/library/spatial/PP.files = rw-r--r-- -jre/languages/R/library/spatial/NAMESPACE = rw-r--r-- -jre/languages/R/library/spatial/DESCRIPTION = rw-r--r-- -jre/languages/R/library/spatial/NEWS = rw-r--r-- -jre/languages/R/library/spatial/INDEX = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig1c.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/davis.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig1b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/cells.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pines.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/caveolae.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pereg.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/hccells.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/agter.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/eagles.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/tokyo.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/grocery.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/drumlin.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pairfn.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/nztrees.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig2a.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/redwood.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig2b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/towns.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/stowns1.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3c.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/schools.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3a.dat = rw-r--r-- -jre/languages/R/library/spatial/R/kr.R = rw-r--r-- -jre/languages/R/library/spatial/R/zzz.R = rw-r--r-- -jre/languages/R/library/spatial/R/spatial = rw-r--r-- -jre/languages/R/library/spatial/R/spatial.rdb = rw-r--r-- -jre/languages/R/library/spatial/R/spatial.rdx = rw-r--r-- -jre/languages/R/library/spatial/R/pp.R = rw-r--r-- -jre/languages/R/library/spatial/Meta/links.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/features.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/package.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/spatial/html/R.css = rw-r--r-- -jre/languages/R/library/spatial/html/00Index.html = rw-r--r-- -jre/languages/R/library/spatial/libs/spatial.so = rwxr-xr-x -jre/languages/R/library/spatial/po/pl/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/en@quot/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/de/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/ko/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/fr/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/help/AnIndex = rw-r--r-- -jre/languages/R/library/spatial/help/aliases.rds = rw-r--r-- -jre/languages/R/library/spatial/help/paths.rds = rw-r--r-- -jre/languages/R/library/spatial/help/spatial.rdb = rw-r--r-- -jre/languages/R/library/spatial/help/spatial.rdx = rw-r--r-- -jre/languages/R/library/graphics/NAMESPACE = rw-r--r-- -jre/languages/R/library/graphics/DESCRIPTION = rw-r--r-- -jre/languages/R/library/graphics/INDEX = rw-r--r-- -jre/languages/R/library/graphics/demo/Japanese.R = rw-r--r-- -jre/languages/R/library/graphics/demo/plotmath.R = rw-r--r-- -jre/languages/R/library/graphics/demo/persp.R = rw-r--r-- -jre/languages/R/library/graphics/demo/graphics.R = rw-r--r-- -jre/languages/R/library/graphics/demo/image.R = rw-r--r-- -jre/languages/R/library/graphics/demo/Hershey.R = rw-r--r-- -jre/languages/R/library/graphics/R/graphics.rdb = rw-r--r-- -jre/languages/R/library/graphics/R/graphics.rdx = rw-r--r-- -jre/languages/R/library/graphics/R/graphics = rw-r--r-- -jre/languages/R/library/graphics/Meta/links.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/features.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/package.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/graphics/html/R.css = rw-r--r-- -jre/languages/R/library/graphics/html/00Index.html = rw-r--r-- -jre/languages/R/library/graphics/libs/graphics.so = rwxr-xr-x -jre/languages/R/library/graphics/help/AnIndex = rw-r--r-- -jre/languages/R/library/graphics/help/aliases.rds = rw-r--r-- -jre/languages/R/library/graphics/help/graphics.rdb = rw-r--r-- -jre/languages/R/library/graphics/help/graphics.rdx = rw-r--r-- -jre/languages/R/library/graphics/help/paths.rds = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.svg = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.pdf = rw-r--r-- -jre/languages/R/library/graphics/help/figures/oma.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/oma.pdf = rw-r--r-- -jre/languages/R/library/graphics/help/figures/mai.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/mai.pdf = rw-r--r-- -jre/languages/R/library/foreign/COPYRIGHTS = rw-r--r-- -jre/languages/R/library/foreign/NAMESPACE = rw-r--r-- -jre/languages/R/library/foreign/DESCRIPTION = rw-r--r-- -jre/languages/R/library/foreign/INDEX = rw-r--r-- -jre/languages/R/library/foreign/R/read.dta.R = rw-r--r-- -jre/languages/R/library/foreign/R/read.ssd.R = rw-r--r-- -jre/languages/R/library/foreign/R/minitab.R = rw-r--r-- -jre/languages/R/library/foreign/R/dbf.R = rw-r--r-- -jre/languages/R/library/foreign/R/octave.R = rw-r--r-- -jre/languages/R/library/foreign/R/spss.R = rw-r--r-- -jre/languages/R/library/foreign/R/R_systat.R = rw-r--r-- -jre/languages/R/library/foreign/R/xport.R = rw-r--r-- -jre/languages/R/library/foreign/R/zzz.R = rw-r--r-- -jre/languages/R/library/foreign/R/read.epiinfo.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign.rdb = rw-r--r-- -jre/languages/R/library/foreign/R/Sread.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign.rdx = rw-r--r-- -jre/languages/R/library/foreign/R/arff.R = rw-r--r-- -jre/languages/R/library/foreign/R/writeForeignSAS.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign = rw-r--r-- -jre/languages/R/library/foreign/R/writeForeignCode.R = rw-r--r-- -jre/languages/R/library/foreign/Meta/links.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/features.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/package.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/foreign/html/R.css = rw-r--r-- -jre/languages/R/library/foreign/html/00Index.html = rw-r--r-- -jre/languages/R/library/foreign/libs/foreign.so = rwxr-xr-x -jre/languages/R/library/foreign/po/pl/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/pl/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/en@quot/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/en@quot/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/de/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/de/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/fr/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/fr/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/files/electric.sav = rw-r--r-- -jre/languages/R/library/foreign/files/Iris.syd = rw-r--r-- -jre/languages/R/library/foreign/files/testdata.sav = rw-r--r-- -jre/languages/R/library/foreign/files/HillRace.SYD = rw-r--r-- -jre/languages/R/library/foreign/files/sids.dbf = rwxr-xr-x -jre/languages/R/library/foreign/help/AnIndex = rw-r--r-- -jre/languages/R/library/foreign/help/aliases.rds = rw-r--r-- -jre/languages/R/library/foreign/help/paths.rds = rw-r--r-- -jre/languages/R/library/foreign/help/foreign.rdb = rw-r--r-- -jre/languages/R/library/foreign/help/foreign.rdx = rw-r--r-- -jre/languages/R/library/compiler/NAMESPACE = rw-r--r-- -jre/languages/R/library/compiler/DESCRIPTION = rw-r--r-- -jre/languages/R/library/compiler/INDEX = rw-r--r-- -jre/languages/R/library/compiler/R/compiler = rw-r--r-- -jre/languages/R/library/compiler/R/compiler.rdx = rw-r--r-- -jre/languages/R/library/compiler/R/compiler.rdb = rw-r--r-- -jre/languages/R/library/compiler/Meta/links.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/features.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/package.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/compiler/html/R.css = rw-r--r-- -jre/languages/R/library/compiler/html/00Index.html = rw-r--r-- -jre/languages/R/library/compiler/help/AnIndex = rw-r--r-- -jre/languages/R/library/compiler/help/aliases.rds = rw-r--r-- -jre/languages/R/library/compiler/help/paths.rds = rw-r--r-- -jre/languages/R/library/compiler/help/compiler.rdx = rw-r--r-- -jre/languages/R/library/compiler/help/compiler.rdb = rw-r--r-- -jre/languages/R/library/Matrix/Copyrights = rw-r--r-- -jre/languages/R/library/Matrix/NEWS.Rd = rw-r--r-- -jre/languages/R/library/Matrix/test-tools-1.R = rw-r--r-- -jre/languages/R/library/Matrix/NAMESPACE = rw-r--r-- -jre/languages/R/library/Matrix/DESCRIPTION = rw-r--r-- -jre/languages/R/library/Matrix/INDEX = rw-r--r-- -jre/languages/R/library/Matrix/test-tools-Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/Doxyfile = rw-r--r-- -jre/languages/R/library/Matrix/test-tools.R = rw-r--r-- -jre/languages/R/library/Matrix/LICENCE = rw-r--r-- -jre/languages/R/library/Matrix/include/Matrix.h = rw-r--r-- -jre/languages/R/library/Matrix/include/Matrix_stubs.c = rw-r--r-- -jre/languages/R/library/Matrix/include/cholmod.h = rw-r--r-- -jre/languages/R/library/Matrix/R/expm.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Auxiliaries.R = rw-r--r-- -jre/languages/R/library/Matrix/R/corMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ngTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/rankMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ndenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/SparseM-conv.R = rw-r--r-- -jre/languages/R/library/Matrix/R/indMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseQR.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Tsparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ntCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/spModels.R = rw-r--r-- -jre/languages/R/library/Matrix/R/LU.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dppMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/AllClass.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Csparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/pMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ntTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/MatrixFactorization.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ddenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/AllGeneric.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/kronecker.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.rdb = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.rdx = rw-r--r-- -jre/languages/R/library/Matrix/R/not.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ngCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dpoMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/denseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/triangularMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/KhatriRao.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtrMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dspMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/bind2.R = rw-r--r-- -jre/languages/R/library/Matrix/R/abIndex.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsyMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/condest.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Rsparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lgTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/eigen.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Math.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseVector.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgeMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nnzero.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ltCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/zzz.R = rw-r--r-- -jre/languages/R/library/Matrix/R/CHMfactor.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Hilbert.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ltTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Ops.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/diagMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix = rw-r--r-- -jre/languages/R/library/Matrix/R/nearPD.R = rw-r--r-- -jre/languages/R/library/Matrix/R/products.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtpMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/colSums.R = rw-r--r-- -jre/languages/R/library/Matrix/R/HBMM.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Summary.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ldenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/bandSparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lgCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/symmetricMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/data.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/links.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/features.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/package.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/Matrix/html/R.css = rw-r--r-- -jre/languages/R/library/Matrix/html/00Index.html = rw-r--r-- -jre/languages/R/library/Matrix/libs/Matrix.so = rwxr-xr-x -jre/languages/R/library/Matrix/po/pl/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/pl/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/en@quot/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/en@quot/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/de/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/de/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/ko/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/fr/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/fr/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/doc/index.html = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Announce.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/SPQR.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/CHOLMOD.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/SuiteSparse_config.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/UserGuides.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/AMD.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/COLAMD.txt = rw-r--r-- -jre/languages/R/library/Matrix/external/lund_a.rsa = rw-r--r-- -jre/languages/R/library/Matrix/external/CAex_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/test3comp.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/utm300.rua = rw-r--r-- -jre/languages/R/library/Matrix/external/USCounties_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/lund_a.mtx = rw-r--r-- -jre/languages/R/library/Matrix/external/wrong.mtx = rw-r--r-- -jre/languages/R/library/Matrix/external/symA.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/KNex_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/symW.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/pores_1.mtx = rw-r--r-- -jre/languages/R/library/Matrix/data/KNex.R = rw-r--r-- -jre/languages/R/library/Matrix/data/CAex.R = rw-r--r-- -jre/languages/R/library/Matrix/data/USCounties.R = rw-r--r-- -jre/languages/R/library/Matrix/help/AnIndex = rw-r--r-- -jre/languages/R/library/Matrix/help/aliases.rds = rw-r--r-- -jre/languages/R/library/Matrix/help/Matrix.rdb = rw-r--r-- -jre/languages/R/library/Matrix/help/Matrix.rdx = rw-r--r-- -jre/languages/R/library/Matrix/help/paths.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/NAMESPACE = rw-r--r-- -jre/languages/R/library/KernSmooth/DESCRIPTION = rw-r--r-- -jre/languages/R/library/KernSmooth/INDEX = rw-r--r-- -jre/languages/R/library/KernSmooth/R/all.R = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth.rdb = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth.rdx = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/links.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/features.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/package.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/html/R.css = rw-r--r-- -jre/languages/R/library/KernSmooth/html/00Index.html = rw-r--r-- -jre/languages/R/library/KernSmooth/libs/KernSmooth.so = rwxr-xr-x -jre/languages/R/library/KernSmooth/po/pl/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/en@quot/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/de/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/ko/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/fr/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/help/AnIndex = rw-r--r-- -jre/languages/R/library/KernSmooth/help/aliases.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/help/paths.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/help/KernSmooth.rdb = rw-r--r-- -jre/languages/R/library/KernSmooth/help/KernSmooth.rdx = rw-r--r-- -jre/languages/R/library/base/CITATION = rw-r--r-- -jre/languages/R/library/base/DESCRIPTION = rw-r--r-- -jre/languages/R/library/base/INDEX = rw-r--r-- -jre/languages/R/library/base/demo/scoping.R = rw-r--r-- -jre/languages/R/library/base/demo/error.catching.R = rw-r--r-- -jre/languages/R/library/base/demo/is.things.R = rw-r--r-- -jre/languages/R/library/base/demo/recursion.R = rw-r--r-- -jre/languages/R/library/base/R/Rprofile = rw-r--r-- -jre/languages/R/library/base/R/base.rdx = rw-r--r-- -jre/languages/R/library/base/R/base.rdb = rw-r--r-- -jre/languages/R/library/base/R/base = rw-r--r-- -jre/languages/R/library/base/Meta/links.rds = rw-r--r-- -jre/languages/R/library/base/Meta/features.rds = rw-r--r-- -jre/languages/R/library/base/Meta/package.rds = rw-r--r-- -jre/languages/R/library/base/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/base/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/base/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/base/html/R.css = rw-r--r-- -jre/languages/R/library/base/html/00Index.html = rw-r--r-- -jre/languages/R/library/base/libs/base.so = rwxr-xr-x -jre/languages/R/library/base/help/AnIndex = rw-r--r-- -jre/languages/R/library/base/help/aliases.rds = rw-r--r-- -jre/languages/R/library/base/help/paths.rds = rw-r--r-- -jre/languages/R/library/base/help/base.rdx = rw-r--r-- -jre/languages/R/library/base/help/base.rdb = rw-r--r-- -jre/languages/R/library/stats/COPYRIGHTS.modreg = rw-r--r-- -jre/languages/R/library/stats/NAMESPACE = rw-r--r-- -jre/languages/R/library/stats/SOURCES.ts = rw-r--r-- -jre/languages/R/library/stats/DESCRIPTION = rw-r--r-- -jre/languages/R/library/stats/INDEX = rw-r--r-- -jre/languages/R/library/stats/demo/smooth.R = rw-r--r-- -jre/languages/R/library/stats/demo/lm.glm.R = rw-r--r-- -jre/languages/R/library/stats/demo/nlm.R = rw-r--r-- -jre/languages/R/library/stats/demo/glm.vr.R = rw-r--r-- -jre/languages/R/library/stats/R/stats.rdx = rw-r--r-- -jre/languages/R/library/stats/R/stats.rdb = rw-r--r-- -jre/languages/R/library/stats/R/stats = rw-r--r-- -jre/languages/R/library/stats/Meta/links.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/features.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/package.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/stats/html/R.css = rw-r--r-- -jre/languages/R/library/stats/html/00Index.html = rw-r--r-- -jre/languages/R/library/stats/libs/stats.so = rwxr-xr-x -jre/languages/R/library/stats/help/AnIndex = rw-r--r-- -jre/languages/R/library/stats/help/aliases.rds = rw-r--r-- -jre/languages/R/library/stats/help/stats.rdx = rw-r--r-- -jre/languages/R/library/stats/help/paths.rds = rw-r--r-- -jre/languages/R/library/stats/help/stats.rdb = rw-r--r-- -jre/languages/R/library/survival/CITATION = rw-r--r-- -jre/languages/R/library/survival/COPYRIGHTS = rw-r--r-- -jre/languages/R/library/survival/NEWS.Rd = rw-r--r-- -jre/languages/R/library/survival/NAMESPACE = rw-r--r-- -jre/languages/R/library/survival/DESCRIPTION = rw-r--r-- -jre/languages/R/library/survival/INDEX = rw-r--r-- -jre/languages/R/library/survival/R/print.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/plot.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cluster.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gamma.S = rw-r--r-- -jre/languages/R/library/survival/R/aareg.taper.R = rw-r--r-- -jre/languages/R/library/survival/R/survival.rdb = rw-r--r-- -jre/languages/R/library/survival/R/pspline.R = rw-r--r-- -jre/languages/R/library/survival/R/plot.survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/print.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/survival.rdx = rw-r--r-- -jre/languages/R/library/survival/R/coxph.getdata.S = rw-r--r-- -jre/languages/R/library/survival/R/coxph.rvar.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlgam.S = rw-r--r-- -jre/languages/R/library/survival/R/survfit.matrix.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survfit.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.cfit.R = rw-r--r-- -jre/languages/R/library/survival/R/survobrien.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/tmerge.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxph.penal.R = rw-r--r-- -jre/languages/R/library/survival/R/plot.cox.zph.S = rw-r--r-- -jre/languages/R/library/survival/R/basehaz.R = rw-r--r-- -jre/languages/R/library/survival/R/format.Surv.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/normalizetime.R = rw-r--r-- -jre/languages/R/library/survival/R/survfit.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/residuals.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gammacon.S = rw-r--r-- -jre/languages/R/library/survival/R/is.na.coxph.penalty.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cch.R = rw-r--r-- -jre/languages/R/library/survival/R/lines.survfit.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/anova.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/is.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/statefig.R = rw-r--r-- -jre/languages/R/library/survival/R/survreg.control.S = rw-r--r-- -jre/languages/R/library/survival/R/survreg.distributions.S = rw-r--r-- -jre/languages/R/library/survival/R/ridge.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.null.S = rw-r--r-- -jre/languages/R/library/survival/R/pyears.R = rw-r--r-- -jre/languages/R/library/survival/R/summary.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/coxph.detail.S = rw-r--r-- -jre/languages/R/library/survival/R/print.pyears.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.wtest.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/survConcordance.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitTurnbull.S = rw-r--r-- -jre/languages/R/library/survival/R/survpenal.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/survfitCI.R = rw-r--r-- -jre/languages/R/library/survival/R/attrassign.R = rw-r--r-- -jre/languages/R/library/survival/R/ratetableold.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survfitms.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.brent.S = rw-r--r-- -jre/languages/R/library/survival/R/match.ratetable.R = rwxr-xr-x -jre/languages/R/library/survival/R/firstlib.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitcoxph.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/cipoisson.R = rw-r--r-- -jre/languages/R/library/survival/R/predict.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/lines.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlgauss.S = rw-r--r-- -jre/languages/R/library/survival/R/print.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.S = rw-r--r-- -jre/languages/R/library/survival/R/strata.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/predict.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/yates.R = rw-r--r-- -jre/languages/R/library/survival/R/neardate.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survdiff.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/coxpenal.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/agexact.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/model.matrix.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/model.frame.survreg.R = rw-r--r-- -jre/languages/R/library/survival/R/lines.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cox.zph.S = rw-r--r-- -jre/languages/R/library/survival/R/survfitms.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gaussian.S = rw-r--r-- -jre/languages/R/library/survival/R/ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlaic.S = rw-r--r-- -jre/languages/R/library/survival/R/tcut.S = rw-r--r-- -jre/languages/R/library/survival/R/dsurvreg.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/clogit.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survexp.S = rw-r--r-- -jre/languages/R/library/survival/R/Surv.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitKM.S = rw-r--r-- -jre/languages/R/library/survival/R/survreg.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.t.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survfit.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/survdiff.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/aeqSurv.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxphlist.S = rw-r--r-- -jre/languages/R/library/survival/R/finegray.R = rw-r--r-- -jre/languages/R/library/survival/R/summary.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/coxpenal.df.S = rw-r--r-- -jre/languages/R/library/survival/R/ratetableDate.R = rw-r--r-- -jre/languages/R/library/survival/R/predict.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/agreg.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.survreglist.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.null.S = rw-r--r-- -jre/languages/R/library/survival/R/quantile.survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/coxexact.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/untangle.specials.S = rw-r--r-- -jre/languages/R/library/survival/R/predict.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/survConcordance.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/agsurv.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controldf.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.survreg.R = rw-r--r-- -jre/languages/R/library/survival/R/survcallback.S = rw-r--r-- -jre/languages/R/library/survival/R/logLik.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/survSplit.R = rw-r--r-- -jre/languages/R/library/survival/R/labels.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/survival = rw-r--r-- -jre/languages/R/library/survival/R/survregDtest.S = rw-r--r-- -jre/languages/R/library/survival/R/xtras.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.control.S = rw-r--r-- -jre/languages/R/library/survival/R/survdiff.fit.S = rw-r--r-- -jre/languages/R/library/survival/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/data.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/links.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/features.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/package.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/survival/html/R.css = rw-r--r-- -jre/languages/R/library/survival/html/00Index.html = rw-r--r-- -jre/languages/R/library/survival/libs/survival.so = rwxr-xr-x -jre/languages/R/library/survival/doc/adjcurve.R = rw-r--r-- -jre/languages/R/library/survival/doc/adjcurve.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/adjcurve.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/index.html = rw-r--r-- -jre/languages/R/library/survival/doc/tests.R = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/multi.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/multi.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/population.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/population.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.R = rw-r--r-- -jre/languages/R/library/survival/doc/population.R = rw-r--r-- -jre/languages/R/library/survival/doc/tests.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/tests.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/compete.R = rw-r--r-- -jre/languages/R/library/survival/doc/compete.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/compete.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.R = rw-r--r-- -jre/languages/R/library/survival/doc/validate.R = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.R = rw-r--r-- -jre/languages/R/library/survival/doc/validate.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/validate.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/multi.R = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/survival/help/survival.rdb = rw-r--r-- -jre/languages/R/library/survival/help/survival.rdx = rw-r--r-- -jre/languages/R/library/survival/help/AnIndex = rw-r--r-- -jre/languages/R/library/survival/help/aliases.rds = rw-r--r-- -jre/languages/R/library/survival/help/paths.rds = rw-r--r-- -jre/languages/R/library/grid/NAMESPACE = rw-r--r-- -jre/languages/R/library/grid/DESCRIPTION = rw-r--r-- -jre/languages/R/library/grid/INDEX = rw-r--r-- -jre/languages/R/library/grid/R/grid.rdb = rw-r--r-- -jre/languages/R/library/grid/R/grid.rdx = rw-r--r-- -jre/languages/R/library/grid/R/grid = rw-r--r-- -jre/languages/R/library/grid/Meta/links.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/features.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/package.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/grid/html/R.css = rw-r--r-- -jre/languages/R/library/grid/html/00Index.html = rw-r--r-- -jre/languages/R/library/grid/libs/grid.so = rwxr-xr-x -jre/languages/R/library/grid/doc/moveline.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/plotexample.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/saveload.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/displaylist.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/viewports.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/interactive.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/grid.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/DivByZero.txt = rw-r--r-- -jre/languages/R/library/grid/doc/rotated.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/changes.txt = rw-r--r-- -jre/languages/R/library/grid/doc/locndimn.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/frame.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/nonfinite.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/sharing.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/grobs.pdf = rw-r--r-- -jre/languages/R/library/grid/help/AnIndex = rw-r--r-- -jre/languages/R/library/grid/help/aliases.rds = rw-r--r-- -jre/languages/R/library/grid/help/grid.rdb = rw-r--r-- -jre/languages/R/library/grid/help/grid.rdx = rw-r--r-- -jre/languages/R/library/grid/help/paths.rds = rw-r--r-- -jre/languages/R/etc/edMakeconf.etc.llvm = rw-r--r-- -jre/languages/R/etc/native-packages = rw-r--r-- -jre/languages/R/etc/configure.ac = rw-r--r-- -jre/languages/R/etc/Makeconf.in = rw-r--r-- -jre/languages/R/etc/ldpaths = rw-r--r-- -jre/languages/R/etc/DEFAULT_CRAN_MIRROR = rw-r--r-- -jre/languages/R/etc/configure = rwxr-xr-x -jre/languages/R/etc/ffibuildtype = rw-r--r-- -jre/languages/R/etc/repositories = rw-r--r-- -jre/languages/R/etc/Renviron.in = rw-r--r-- -jre/languages/R/etc/ldpaths.in = rw-r--r-- -jre/languages/R/etc/VERSION = rw-r--r-- -jre/languages/R/etc/Makeconf = rw-r--r-- -jre/languages/R/etc/Renviron = rw-r--r-- -jre/languages/R/etc/edMakeconf.etc = rw-r--r-- -jre/languages/R/etc/javaconf = rw-r--r-- -jre/languages/R/etc/tools/GETVERSION = rw-r--r-- -jre/languages/R/etc/tools/ldAIX4 = rw-r--r-- -jre/languages/R/etc/tools/copy-if-change = rw-r--r-- -jre/languages/R/etc/tools/install-sh = rwxr-xr-x -jre/languages/R/etc/tools/help2man.pl = rw-r--r-- -jre/languages/R/etc/tools/config.rpath = rwxr-xr-x -jre/languages/R/etc/tools/ltmain.sh = rw-r--r-- -jre/languages/R/etc/tools/link-recommended = rwxr-xr-x -jre/languages/R/etc/tools/Makefile = rw-r--r-- -jre/languages/R/etc/tools/config.guess = rwxr-xr-x -jre/languages/R/etc/tools/missing = rwxr-xr-x -jre/languages/R/etc/tools/README = rw-r--r-- -jre/languages/R/etc/tools/GETCONFIG = rw-r--r-- -jre/languages/R/etc/tools/config.sub = rwxr-xr-x -jre/languages/R/etc/tools/GETMAKEVAL = rwxr-xr-x -jre/languages/R/etc/tools/updatefat = rwxr-xr-x -jre/languages/R/etc/tools/install-info.pl = rw-r--r-- -jre/languages/R/etc/tools/move-if-change = rw-r--r-- -jre/languages/R/etc/tools/getsp.java = rw-r--r-- -jre/languages/R/etc/tools/Makefile.in = rw-r--r-- -jre/languages/R/etc/tools/rsync-recommended = rwxr-xr-x -jre/languages/R/etc/tools/GETDISTNAME = rwxr-xr-x -jre/languages/R/etc/tools/mdate-sh = rwxr-xr-x -jre/languages/R/etc/m4/ltversion.m4 = rw-r--r-- -jre/languages/R/etc/m4/libtool.m4 = rw-r--r-- -jre/languages/R/etc/m4/ltoptions.m4 = rw-r--r-- -jre/languages/R/etc/m4/cairo.m4 = rw-r--r-- -jre/languages/R/etc/m4/ltsugar.m4 = rw-r--r-- -jre/languages/R/etc/m4/Makefile = rw-r--r-- -jre/languages/R/etc/m4/stat-time.m4 = rw-r--r-- -jre/languages/R/etc/m4/README = rw-r--r-- -jre/languages/R/etc/m4/bigendian.m4 = rw-r--r-- -jre/languages/R/etc/m4/codeset.m4 = rw-r--r-- -jre/languages/R/etc/m4/gettext.m4 = rw-r--r-- -jre/languages/R/etc/m4/R.m4 = rw-r--r-- -jre/languages/R/etc/m4/cxx_11.m4 = rw-r--r-- -jre/languages/R/etc/m4/clibs.m4 = rw-r--r-- -jre/languages/R/etc/m4/gettext-lib.m4 = rw-r--r-- -jre/languages/R/etc/m4/Makefile.in = rw-r--r-- -jre/languages/R/etc/m4/lt~obsolete.m4 = rw-r--r-- -jre/languages/R/etc/m4/openmp.m4 = rw-r--r-- -jre/languages/R/etc/src/include/config.h.in = rw-r--r-- -jre/languages/R/share/encodings/character-sets = rw-r--r-- -jre/languages/R/share/encodings/Adobe-glyphlist = rw-r--r-- -jre/languages/R/share/R/tests-startup.R = rw-r--r-- -jre/languages/R/share/R/examples-header.R = rw-r--r-- -jre/languages/R/share/R/examples-footer.R = rw-r--r-- -jre/languages/R/share/R/REMOVE.R = rw-r--r-- -jre/languages/R/share/R/nspackloader.R = rw-r--r-- -jre/languages/R/share/java/README = rw-r--r-- -jre/languages/R/share/java/getsp.class = rw-r--r-- -jre/languages/R/share/make/shlib.mk = rw-r--r-- -jre/languages/R/share/make/check_vars_ini.mk = rw-r--r-- -jre/languages/R/share/make/lazycomp.mk = rw-r--r-- -jre/languages/R/share/make/winshlib.mk = rw-r--r-- -jre/languages/R/share/make/config.mk = rw-r--r-- -jre/languages/R/share/make/clean.mk = rw-r--r-- -jre/languages/R/share/make/vars.mk = rw-r--r-- -jre/languages/R/share/make/basepkg.mk = rw-r--r-- -jre/languages/R/share/make/check_vars_out.mk = rw-r--r-- -jre/languages/R/share/Rd/macros/system.Rd = rw-r--r-- -jre/languages/R/doc/COPYRIGHTS = rw-r--r-- -jre/languages/R/doc/BioC_mirrors.csv = rw-r--r-- -jre/languages/R/doc/NEWS.Rd = rw-r--r-- -jre/languages/R/doc/NEWS.pdf = rw-r--r-- -jre/languages/R/doc/R.aux = rw-r--r-- -jre/languages/R/doc/AUTHORS = rw-r--r-- -jre/languages/R/doc/Makefile = rw-r--r-- -jre/languages/R/doc/FAQ = rw-r--r-- -jre/languages/R/doc/RESOURCES = rw-r--r-- -jre/languages/R/doc/Rscript.1 = rw-r--r-- -jre/languages/R/doc/CRAN_mirrors.csv = rw-r--r-- -jre/languages/R/doc/NEWS.2 = rw-r--r-- -jre/languages/R/doc/COPYING = rw-r--r-- -jre/languages/R/doc/NEWS.rds = rw-r--r-- -jre/languages/R/doc/NEWS = rw-r--r-- -jre/languages/R/doc/NEWS.2.Rd = rw-r--r-- -jre/languages/R/doc/THANKS = rw-r--r-- -jre/languages/R/doc/KEYWORDS = rw-r--r-- -jre/languages/R/doc/Makefile.in = rw-r--r-- -jre/languages/R/doc/Makefile.win = rw-r--r-- -jre/languages/R/doc/R.1 = rw-r--r-- -jre/languages/R/doc/NEWS.0 = rw-r--r-- -jre/languages/R/doc/KEYWORDS.db = rw-r--r-- -jre/languages/R/doc/NEWS.1 = rw-r--r-- -jre/languages/R/doc/html/favicon.ico = rw-r--r-- -jre/languages/R/doc/html/index.html = rw-r--r-- -jre/languages/R/doc/html/about.html = rw-r--r-- -jre/languages/R/doc/html/up.jpg = rw-r--r-- -jre/languages/R/doc/html/Makefile = rw-r--r-- -jre/languages/R/doc/html/packages.html = rw-r--r-- -jre/languages/R/doc/html/NEWS.2.html = rw-r--r-- -jre/languages/R/doc/html/R-admin.html = rw-r--r-- -jre/languages/R/doc/html/index-default.html = rw-r--r-- -jre/languages/R/doc/html/NEWS.html = rw-r--r-- -jre/languages/R/doc/html/resources.html = rw-r--r-- -jre/languages/R/doc/html/left.jpg = rw-r--r-- -jre/languages/R/doc/html/Notes = rw-r--r-- -jre/languages/R/doc/html/logo.jpg = rw-r--r-- -jre/languages/R/doc/html/R.css = rw-r--r-- -jre/languages/R/doc/html/Rlogo.svg = rw-r--r-- -jre/languages/R/doc/html/Search.html = rw-r--r-- -jre/languages/R/doc/html/Rlogo.pdf = rw-r--r-- -jre/languages/R/doc/html/SearchOn.html = rw-r--r-- -jre/languages/R/doc/html/Makefile.in = rw-r--r-- -jre/languages/R/doc/html/right.jpg = rw-r--r-- -jre/languages/R/doc/html/packages-head-utf8.html = rw-r--r-- -jre/languages/R/doc/manual/R-exts.texi = rw-r--r-- -jre/languages/R/doc/manual/pdfcolor.tex = rw-r--r-- -jre/languages/R/doc/manual/refman.top = rw-r--r-- -jre/languages/R/doc/manual/ISBN = rw-r--r-- -jre/languages/R/doc/manual/resources.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile = rw-r--r-- -jre/languages/R/doc/manual/version.texi = rw-r--r-- -jre/languages/R/doc/manual/R-defs.texi = rw-r--r-- -jre/languages/R/doc/manual/R-exts.c = rw-r--r-- -jre/languages/R/doc/manual/rw-FAQ.texi = rw-r--r-- -jre/languages/R/doc/manual/R-FAQ.texi = rw-r--r-- -jre/languages/R/doc/manual/R-intro.R = rw-r--r-- -jre/languages/R/doc/manual/quot.sed = rw-r--r-- -jre/languages/R/doc/manual/README = rw-r--r-- -jre/languages/R/doc/manual/Rfaq.css = rw-r--r-- -jre/languages/R/doc/manual/refman.bot = rw-r--r-- -jre/languages/R/doc/manual/R-intro.texi = rw-r--r-- -jre/languages/R/doc/manual/stamp-images-html = rw-r--r-- -jre/languages/R/doc/manual/dir = rw-r--r-- -jre/languages/R/doc/manual/R-data.texi = rw-r--r-- -jre/languages/R/doc/manual/epsf.tex = rw-r--r-- -jre/languages/R/doc/manual/Rman.css = rw-r--r-- -jre/languages/R/doc/manual/R-ints.texi = rw-r--r-- -jre/languages/R/doc/manual/R-exts.R = rw-r--r-- -jre/languages/R/doc/manual/R-admin.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile.in = rw-r--r-- -jre/languages/R/doc/manual/R-lang.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile.win = rw-r--r-- -jre/languages/R/doc/manual/images/hist.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/hist.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig12.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig11.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/fig11.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig12.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ecdf.png = rw-r--r-- -jre/languages/R/doc/manual/images/ice.png = rw-r--r-- -jre/languages/R/doc/manual/images/QQ.png = rw-r--r-- -jre/languages/R/doc/manual/images/QQ.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ecdf.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ice.pdf = rw-r--r-- -jre/languages/R/jline.jar = rw-r--r-- -jre/languages/R/antlr4.jar = rw-r--r-- -jre/languages/R/xz-1.8.jar = rw-r--r-- -jre/languages/R/fastr-launcher.jar = rw-r--r-- -jre/languages/R/bin/exec/R = rwxr-xr-x -jre/languages/R/bin/Rscript = rwxr-xr-x -jre/languages/R/3rd_party_licenses_fastr.txt = rw-r--r-- -jre/languages/R/native-image.properties = rw-r--r-- -jre/languages/R/README_FASTR = rw-r--r-- -jre/languages/R/LICENSE_FASTR = rw-r--r-- -LICENSE_FASTR = rwxrwxrwx -3rd_party_licenses_fastr.txt = rwxrwxrwx -bin/Rscript = rwxrwxrwx -bin/R = rwxrwxrwx -jre/languages/R/release = rw-rw-r-- -jre/bin/Rscript = rwxrwxrwx -jre/bin/R = rwxrwxrwx \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/symlinks deleted file mode 100644 index 0aeecbe46387..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/META-INF/symlinks +++ /dev/null @@ -1,3 +0,0 @@ -LICENSE_FASTR = jre/languages/R/LICENSE_FASTR -bin/R = ../jre/bin/R -jre/bin/R = ../languages/R/bin/R \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/LICENSE_FASTR b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/LICENSE_FASTR deleted file mode 100644 index 54975fbea0e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/LICENSE_FASTR +++ /dev/null @@ -1,720 +0,0 @@ -Product License - GraalVM Community Edition 1.0 R Language Component - -This is a release of GraalVM Community Edition 1.0 R Language Component. This -particular copy of the software is released under version 3 of GNU General -Public License. - -Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved - -=========================================================================== - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - -=========================================================================== - - WRITTEN OFFER FOR SOURCE CODE -For any software that you receive from Oracle in binary form which is licensed -under an open source license that gives you the right to receive the source -code for that binary, you can obtain a copy of the applicable source code by -visiting http://www.oracle.com/goto/opensourcecode. If the source code for the -binary was not provided to you with the binary, you can also receive a copy of -the source code on physical media by submitting a written request to the -address listed below or by sending an email to Oracle using the following link: - http://www.oracle.com/goto/opensourcecode/request. - -Oracle America, Inc. -Attn: Senior Vice President -Development and Engineering Legal -500 Oracle Parkway, 10th Floor -Redwood Shores, CA 94065 - -Your request should include: - • The name of the binary for which you are requesting the source code - • The name and version number of the Oracle product containing the binary - • The date you received the Oracle product - • Your name - • Your company name (if applicable) - • Your return mailing address and email, and - • A telephone number in the event we need to reach you. - -We may charge you a fee to cover the cost of physical media and processing. -Your request must be sent - a. within three (3) years of the date you received the Oracle product that -included the binary that is the subject of your request, or - b. in the case of code licensed under the GPL v3 for as long as Oracle -offers spare parts or customer support for that product model. - -=========================================================================== diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/README_FASTR b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/README_FASTR deleted file mode 100644 index a5283f739238..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/README_FASTR +++ /dev/null @@ -1,70 +0,0 @@ -[![Join the chat at https://gitter.im/graalvm/graal-core](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/graalvm/graal-core?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -A high-performance implementation of the R programming language, built on GraalVM. - -FastR aims to be: -* [efficient](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#4ab6): executing R language scripts faster than any other R runtime -* [polyglot](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#0f5c): allowing [polyglot interoperability](https://www.graalvm.org/docs/reference-manual/polyglot/) with other languages in the GraalVM ecosystem. -* [compatible](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#fff5): providing support for existing packages and the R native interface -* [embeddable](https://github.com/graalvm/examples/tree/master/r_java_embedding): allowing integration using the R embedding API or the GraalVM polyglot embedding SDK - - -The screenshot below shows Java application with embedded FastR engine. -The plot below was generated by `ggplot2` running on FastR and it shows -peak performance of the [raytracing example](http://www.tylermw.com/throwing-shade/). -The measurements were [reproduced independently](https://nextjournal.com/sdanisch/fastr-benchmark). - -![Java embedding](documentation/assets/javaui.png) -![Speedup](documentation/assets/speedup.png) - - ## Getting Started -See the documentation on the GraalVM website on how to [get GraalVM](https://www.graalvm.org/docs/getting-started/) and [install and use FastR](http://www.graalvm.org/docs/reference-manual/languages/r/). - -``` -$ $GRAALVM/bin/R -Type 'q()' to quit R. -> print("Hello R!") -[1] "Hello R!" -> -``` - -## Documentation - -The reference manual for FastR, which explains its advantages, its current limitations, compatibility and additional functionality is available on the [GraalVM website](http://www.graalvm.org/docs/reference-manual/languages/r/). - -Further documentation, including contributor/developer-oriented information, is in the [documentation folder](documentation/Index.md) of this repository. - -## Current Status - -The goal of FastR is to be a drop-in replacement for GNU-R, the reference implementation of the R language. -FastR faithfully implements the R language, and any difference in behavior is considered to be a bug. - -FastR is capable of running binary R packages built for GNU-R as long as those packages properly use the R extensions C API (for best results, it is recommended to install R packages from source). -FastR supports R graphics via the grid package and packages based on grid (like lattice and ggplot2). -We are currently working towards support for the base graphics package. -FastR currently supports many of the popular R packages, such as ggplot2, jsonlite, testthat, assertthat, knitr, Shiny, Rcpp, rJava, quantmod and more… - -Moreover, support for dplyr and data.table are on the way. -We are actively monitoring and improving FastR support for the most popular packages published on CRAN including all the tidyverse packages. -However, one should take into account the experimental state of FastR, there can be packages that are not compatible yet, and if you try it on a complex R application, it can stumble on those. - -## Stay connected with the community - -See [graalvm.org/community](https://www.graalvm.org/community/) on how to stay connected with the development community. -The discussion on [gitter](https://gitter.im/graalvm/graal-core) is a good way to get in touch with us. - -We would like to grow the FastR open-source community to provide a free R implementation atop the Truffle/Graal stack. -We encourage contributions, and invite interested developers to join in. -Prospective contributors need to sign the [Oracle Contributor Agreement (OCA)](http://www.oracle.com/technetwork/community/oca-486395.html). -The access point for contributions, issues and questions about FastR is the [GitHub repository](https://github.com/oracle/fastr). - -## Authors - -FastR is developed by Oracle Labs and is based on [the GNU-R runtime](http://www.r-project.org/). -It contains contributions by researchers at Purdue University ([purdue-fastr](https://github.com/allr/purdue-fastr)), Northeastern University, JKU Linz, TU Dortmund and TU Berlin. - -## License - -FastR is available under a GPLv3 license. - - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/doc/THANKS b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/doc/THANKS deleted file mode 100644 index 6f8eb3ee226a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/doc/THANKS +++ /dev/null @@ -1,70 +0,0 @@ -R would not be what it is today without the invaluable help of these -people outside of the R core team, who contributed by donating code, bug -fixes and documentation: - -Valerio Aimale, Suharto Anggono, Thomas Baier, Henrik Bengtsson, Roger Bivand, -Ben Bolker, David Brahm, G"oran Brostr"om, Patrick Burns, Vince Carey, -Saikat DebRoy, Matt Dowle, Brian D'Urso, Lyndon Drake, Dirk Eddelbuettel, -Claus Ekstrom, Sebastian Fischmeister, John Fox, Paul Gilbert, -Yu Gong, Gabor Grothendieck, Frank E Harrell Jr, Peter M. Haverty, -Torsten Hothorn, Robert King, Kjetil Kjernsmo, Roger Koenker, Philippe Lambert, -Jan de Leeuw, Jim Lindsey, Patrick Lindsey, Catherine Loader, -Gordon Maclean, John Maindonald, David Meyer, Ei-ji Nakama, -Jens Oehlschaegel, Steve Oncley, Richard O'Keefe, Hubert Palme, -Roger D. Peng, Jose' C. Pinheiro, Tony Plate, Anthony Rossini, -Jonathan Rougier, Petr Savicky, Guenther Sawitzki, Marc Schwartz, -Arun Srinivasan, Detlef Steuer, Bill Simpson, Gordon Smyth, Adrian Trapletti, -Terry Therneau, Rolf Turner, Bill Venables, Gregory R. Warnes, -Andreas Weingessel, Morten Welinder, James Wettenhall, Simon Wood, and -Achim Zeileis. - -Others have written code that has been adopted by R and is -acknowledged in the code files, including - -J. D. Beasley, David J. Best, Richard Brent, Kevin Buhr, Michael -A. Covington, Bill Cleveland, Robert Cleveland,, G. W. Cran, -C. G. Ding, Ulrich Drepper, Paul Eggert, J. O. Evans, David M. Gay, -H. Frick, G. W. Hill, Richard H. Jones, Eric Grosse, Shelby Haberman, -Bruno Haible, John Hartigan, Andrew Harvey, Trevor Hastie, Min Long -Lam, George Marsaglia, K. J. Martin, Gordon Matzigkeit, -C. R. Mckenzie, Jean McRae, Cyrus Mehta, Fionn Murtagh, John C. Nash, -Finbarr O'Sullivan, R. E. Odeh, William Patefield, Nitin Patel, Alan -Richardson, D. E. Roberts, Patrick Royston, Russell Lenth, Ming-Jen -Shyu, Richard C. Singleton, S. G. Springer, Supoj Sutanthavibul, Irma -Terpenning, G. E. Thomas, Rob Tibshirani, Wai Wan Tsang, Berwin -Turlach, Gary V. Vaughan, Michael Wichura, Jingbo Wang, M. A. Wong, -and the Free Software Foundation (for autoconf code and utilities). -See also files under src/extras. - -Many more, too numerous to mention here, have contributed by sending bug -reports and suggesting various improvements. - -Simon Davies whilst at the University of Auckland wrote the original -version of glm(). - -Julian Harris and Wing Kwong (Tiki) Wan whilst at the University of -Auckland assisted Ross Ihaka with the original Macintosh port. - -R was inspired by the S environment which has been principally -developed by John Chambers, with substantial input from Douglas Bates, -Rick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and -Allan Wilks. - -A special debt is owed to John Chambers who has graciously contributed -advice and encouragement in the early days of R and later became a -member of the core team. - - - -The R Foundation may decide to give out @R-project.org -email addresses to contributors to the R Project (even without making them -members of the R Foundation) when in the view of the R Foundation this -would help advance the R project. - -The R Core Group, Roger Bivand, Jennifer Bryan, Di Cook, Dirk Eddelbuettel, -John Fox, Bettina Grün, Frank Harrell, Torsten Hothorn, Stefano Iacus, -Julie Josse, Balasubramanian Narasimhan, Marc Schwartz, Heather Turner, -Bill Venables, Hadley Wickham and Achim Zeileis are the ordinary members of -the R Foundation. -In addition, David Meyer and Simon Wood are also e-addressable by -.@R-project.org. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/include/linked b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/include/linked deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/library/utils/DESCRIPTION b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/library/utils/DESCRIPTION deleted file mode 100644 index e8a417ec3fe6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/library/utils/DESCRIPTION +++ /dev/null @@ -1,11 +0,0 @@ -Package: utils -Version: 3.5.1 -Priority: base -Title: The R Utils Package -Author: R Core Team and contributors worldwide -Maintainer: R Core Team -Description: R utility functions. -License: Part of R 3.5.1 -Suggests: methods, xml2, commonmark -NeedsCompilation: yes -Built: R 3.5.1; x86_64-apple-darwin18.2.0; 2019-04-02 04:04:54 UTC; unix diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/native-image.properties deleted file mode 100644 index 0b896fe5ce53..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/native-image.properties +++ /dev/null @@ -1,28 +0,0 @@ -# This file contains native-image arguments needed to fastr -# - -ImageName = RMain - -Requires = tool:nfi \ - tool:chromeinspector \ - tool:nfi \ - tool:profiler - -JavaArgs = \ - -Dfastr.resource.factory.class=com.oracle.truffle.r.nodes.builtin.EagerResourceHandlerFactory \ - -Dfastr.internal.usemxbeans=false \ - -Dfastr.internal.usenativeeventloop=false \ - -Dfastr.internal.defaultdownloadmethod=wget \ - -Dfastr.internal.ignorejvmargs=true \ - -Dfastr.use.remote.grid.awt.device=true - -LauncherClass = com.oracle.truffle.r.launcher.RMain -LauncherClassPath = lib/graalvm/launcher-common.jar:languages/R/fastr-launcher.jar - -Args = --enable-http \ - -H:MaxRuntimeCompileMethods=8000 \ - -H:+UnlockExperimentalVMOptions \ - -H:-TruffleCheckFrameImplementation \ - -H:+TruffleCheckNeverPartOfCompilation \ - -H:-UseServiceLoaderFeature \ - -H:-UnlockExperimentalVMOptions diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/release deleted file mode 100644 index eb822705c23a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=macos -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/share/java/README b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/share/java/README deleted file mode 100644 index 6201c0580eb8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/r/jre/languages/R/share/java/README +++ /dev/null @@ -1,3 +0,0 @@ -getsp.class has source tools/getsp.java. - -It is installed for use by R CMD javareconf. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/MANIFEST.MF deleted file mode 100644 index 47deba0d850a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/MANIFEST.MF +++ /dev/null @@ -1,14 +0,0 @@ -Bundle-Name: TruffleRuby -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Version: 19.3.0.0 -Require-Bundle: llvm-toolchain -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.1.0.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/ruby -x-GraalVM-Message-PostInst: \nIMPORTANT NOTE:\n---------------\nThe Ruby - openssl C extension needs to be recompiled on your system to work with - the installed libssl.\nFirst, make sure TruffleRuby's dependencies are i - nstalled, which are described at:\n https://github.com/oracle/truffleru - by/blob/master/README.md#dependencies\nThen run the following command:\n - ${graalvm_home}/jre/languages/ruby/lib/truffle/post_install_hook - .sh diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/permissions deleted file mode 100644 index bb398974f8a7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/permissions +++ /dev/null @@ -1,7 +0,0 @@ -bin/truffleruby = rwxrwxrwx -bin/rake = rwxrwxrwx -jre/bin/truffleruby = rwxrwxrwx -jre/bin/rake = rwxrwxrwx -LICENSE_TRUFFLERUBY.md = rwxrwxrwx -jre/languages/ruby/release = rw-rw-r-- -jre/languages/ruby/lib/cext/include/sulong/polyglot.h = rw-rw-r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/symlinks deleted file mode 100644 index fa711df113bd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/META-INF/symlinks +++ /dev/null @@ -1,6 +0,0 @@ -bin/ruby = ../jre/bin/ruby -bin/rake = ../jre/bin/rake -jre/bin/truffleruby = ../languages/ruby/bin/truffleruby -jre/bin/rake = ../languages/ruby/bin/rake -LICENSE_TRUFFLERUBY.md = jre/languages/ruby/LICENSE_TRUFFLERUBY.md -jre/languages/ruby/bin/ruby = truffleruby \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/LICENSE_TRUFFLERUBY.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/LICENSE_TRUFFLERUBY.md deleted file mode 100644 index 8e3aea7e3802..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/LICENSE_TRUFFLERUBY.md +++ /dev/null @@ -1 +0,0 @@ -Some license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/README.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/README.md deleted file mode 100644 index e23317b39c52..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/README.md +++ /dev/null @@ -1,218 +0,0 @@ -![TruffleRuby logo](logo/png/truffleruby_logo_horizontal_medium.png) - -A high performance implementation of the Ruby programming language. Built on -[GraalVM](http://graalvm.org/) by [Oracle Labs](https://labs.oracle.com). - -## Getting started - -There are three ways to install TruffleRuby: - -* Via [GraalVM](doc/user/installing-graalvm.md), which includes support for - other languages such as JavaScript, R and Python and supports both the - [*native* and *JVM* configurations](#truffleruby-configurations). - Inside GraalVM will then be a `bin/ruby` command that runs TruffleRuby. - We recommend that you use a [Ruby manager](doc/user/ruby-managers.md#configuring-ruby-managers-for-the-full-graalvm-distribution) - to use TruffleRuby inside GraalVM. - -* Via your [Ruby manager/installer](doc/user/ruby-managers.md) (RVM, rbenv, - chruby, ruby-build, ruby-install). This contains only TruffleRuby, in the - [*native* configuration](#truffleruby-configurations), making it a smaller - download. It is meant for users just wanting a Ruby implementation and already - using a Ruby manager. - -* Using the [standalone distribution](doc/user/standalone-distribution.md) - as a simple binary tarball. This distribution is also useful for - [testing TruffleRuby in CI](doc/user/standalone-distribution.md). - On [TravisCI](https://docs.travis-ci.com/user/languages/ruby#truffleruby), you can simply use: - ```yaml - language: ruby - rvm: - - truffleruby - ``` - -You can use `gem` to install Gems as normal. - -You can also build TruffleRuby from source, see the -[building instructions](doc/contributor/workflow.md), and using -[Docker](doc/contributor/docker.md). - -Please report any issue you might find on [GitHub](https://github.com/oracle/truffleruby/issues). - -## Aim - -TruffleRuby aims to: - -* Run idiomatic Ruby code faster -* Run Ruby code in parallel -* Boot Ruby applications in less time -* Execute C extensions in a managed environment -* Add fast and low-overhead interoperability with languages like Java, JavaScript, Python and R -* Provide new tooling such as debuggers and monitoring -* All while maintaining very high compatibility with the standard implementation of Ruby - -## TruffleRuby configurations - -There are two main configurations of TruffleRuby: *native* and *JVM*. It's -important to understand the different configurations of TruffleRuby, as each has -different capabilities and performance characteristics. You should pick the -execution mode that is appropriate for your application. - -TruffleRuby by default runs in the *native* -configuration. In this configuration, TruffleRuby is ahead-of-time compiled to a -standalone native executable. This means that you don't need a JVM installed on -your system to use it. The advantage of the native configuration is that it -[starts about as fast as MRI](doc/contributor/svm.md), it may use less memory, -and it becomes fast in less time. The disadvantage of the native configuration -is that you can't use Java tools like VisualVM, you can't use Java -interoperability, and *peak performance may be lower than on the JVM*. The -native configuration is used by default, but you can also request it using -`--native`. To use polyglot programming with the *native* configuration, you -need to use the `--polyglot` flag. To check you are using the *native* -configuration, `ruby --version` should mention `Native`. - -TruffleRuby can also be used in the *JVM* configuration, where it runs as a -normal Java application on the JVM, as any other Java application would. The -advantage of the JVM configuration is that you can use Java interoperability, -and *peak performance may be higher than the native configuration*. The -disadvantage of the JVM configuration is that it takes much longer to start and -to get fast, and may use more memory. The JVM configuration is requested using -`--jvm`. To check you are using the *JVM* configuration, `ruby --version` should -not mention `Native`. - -If you are running a short-running program you probably want the default, -*native*, configuration. If you are running a long-running program and want the -highest possible performance you probably want the *JVM* configuration, by using -`--jvm`. - -At runtime you can tell if you are using the native configuration using -`TruffleRuby.native?`. - -You won't encounter it when using TruffleRuby from the GraalVM, but there is -also another configuration which is TruffleRuby running on the JVM but with the -Graal compiler not available. This configuration will have much lower -performance and should normally only be used for development. `ruby --version` -will mention `Interpreter` for this configuration. - -## System compatibility - -TruffleRuby is actively tested on these systems: - -* Oracle Linux 7 -* Ubuntu 18.04 LTS -* Ubuntu 16.04 LTS -* Fedora 28 -* macOS 10.14 (Mojave) -* macOS 10.13 (High Sierra) - -You may find that TruffleRuby will not work if you severely restrict the -environment, for example by unmounting system filesystems such as `/dev/shm`. - -## Dependencies - -* [LLVM](doc/user/installing-llvm.md) to build and run C extensions -* [libssl](doc/user/installing-libssl.md) for the `openssl` C extension -* [zlib](doc/user/installing-zlib.md) for the `zlib` C extension - -Without these dependencies, many libraries including RubyGems will not work. -TruffleRuby will try to print a nice error message if a dependency is missing, -but this can only be done on a best effort basis. - -You may also need to set up a [UTF-8 locale](doc/user/utf8-locale.md). - -## Current status - -We recommend that people trying TruffleRuby on their gems and applications -[get in touch with us](#contact) for help. - -TruffleRuby is progressing fast but is currently probably not ready for you to -try running your full Ruby application on. However it is ready for -experimentation and curious end-users to try on their gems and smaller -applications. - -TruffleRuby runs Rails, and passes the majority of the Rails test suite. But it -is missing support for Nokogiri and ActiveRecord database drivers which makes it -not practical to run real Rails applications at the moment. - -You will find that many C extensions will not work without modification. - -## Migration from MRI - -TruffleRuby should in most cases work as a drop-in replacement for MRI, but you -should read about our [compatibility](doc/user/compatibility.md). - -## Migration from JRuby - -For many use cases TruffleRuby should work as a drop-in replacement for JRuby. -However, our approach to integration with Java is different to JRuby so you -should read our [migration guide](doc/user/jruby-migration.md). - -## Documentation - -Extensive documentation is available in [`doc`](doc). -[`doc/user`](doc/user) documents how to use TruffleRuby and -[`doc/contributor`](doc/contributor) documents how to develop TruffleRuby. - -## Contact - -The best way to get in touch with us is to join us in -https://gitter.im/graalvm/truffleruby, but you can also Tweet to -[@TruffleRuby](https://twitter.com/truffleruby), or email -chris.seaton@oracle.com. - -## Mailing list - -Announcements about GraalVM, including TruffleRuby, are made on the -[graal-dev](http://mail.openjdk.java.net/mailman/listinfo/graal-dev) mailing list. - -## Authors - -The main authors of TruffleRuby in order of joining the project are: - -* Chris Seaton -* Benoit Daloze -* Kevin Menard -* Petr Chalupa -* Brandon Fish -* Duncan MacGregor -* Christian Wirth - -Additionally: - -* Thomas Würthinger -* Matthias Grimmer -* Josef Haider -* Fabio Niephaus -* Matthias Springer -* Lucas Allan Amorim -* Aditya Bhardwaj - -Collaborations with: - -* [Institut für Systemsoftware at Johannes Kepler University - Linz](http://ssw.jku.at) - -And others. - -## Security - -See the [security documentation](doc/user/security.md). - -## Licence - -TruffleRuby is copyright (c) 2013-2019 Oracle and/or its affiliates, and is made -available to you under the terms of any one of the following three licenses: - -* Eclipse Public License version 1.0, or -* GNU General Public License version 2, or -* GNU Lesser General Public License version 2.1. - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. - -## Attribution - -TruffleRuby is a fork of [JRuby](https://github.com/jruby/jruby), combining it -with code from the [Rubinius](https://github.com/rubinius/rubinius) project, and -also containing code from the standard implementation of Ruby, -[MRI](https://github.com/ruby/ruby). diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/legal/ruby-licence.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/legal/ruby-licence.txt deleted file mode 100644 index f06056fb45fb..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/legal/ruby-licence.txt +++ /dev/null @@ -1,56 +0,0 @@ -Ruby is copyrighted free software by Yukihiro Matsumoto . -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/19.3.0.0/ruby/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog-19.3.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog-19.3.properties deleted file mode 100644 index a01e64f46bf5..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog-19.3.properties +++ /dev/null @@ -1,68 +0,0 @@ -org.graalvm.1.0.0.0_linux_amd64=GraalVM 1.0.1.0 linux/amd64 -org.graalvm.1.1.0.1_linux_amd64=GraalVM 1.1.0.1 linux/amd64 -org.graalvm.1.1.1-0.rc.1_linux_amd64=GraalVM 1.1.0.1 linux/amd64 -org.graalvm.19.3.0.0_linux_amd64=GraalVM 19.3 linux/amd64 - -Component.linux_amd64/1.0.0.0/org.graalvm.python=python/1.0.0.0 -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Version=1.0.0.0 - -Component.linux_amd64/1.1.0.0/org.graalvm.python=python/1.1.0.0 -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Version=1.1.0.0 - -Component.linux_amd64/1.0.1.0/org.graalvm.r=r/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Version=1.0.1.0 - -Component.linux_amd64/1.1.0.1/org.graalvm.r=r/1.1.0.1 -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.1)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Version=1.1.0.1 - -Component.linux_amd64/1.0.0.0/org.graalvm.ruby=ruby/1.0.0.0 -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Version=1.0.0.0 - - -Component.linux_amd64/19.3.0.0/org.graalvm.r=19.3.0.0/r -Component.linux_amd64/19.3.0.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/19.3.0.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3.0.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/19.3.0.0/org.graalvm.r-Bundle-Version=19.3.0.0 -Component.linux_amd64/19.3.0.0/org.graalvm.r-Require-Bundle=org.graalvm.llvm-toolchain - -Component.linux_amd64/19.3.0.0/org.graalvm.llvm_toolchain=19.3.0.0/llvm-toolchain -Component.linux_amd64/19.3.0.0/org.graalvm.llvm_toolchain-Bundle-Symbolic-Name=org.graalvm.llvm-toolchain -Component.linux_amd64/19.3.0.0/org.graalvm.llvm_toolchain-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=19.3.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3.0.0/org.graalvm.llvm_toolchain-Bundle-Name=LLVM tools chain -Component.linux_amd64/19.3.0.0/org.graalvm.llvm_toolchain-Bundle-Version=19.3.0.0 - - -Component.linux_amd64/1.0.0.0/org.graalvm=core/graalvm-1.0.0.0.jar -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-Version=1.0.0.0 - -Component.linux_amd64/1.1.0.1/org.graalvm=core/graalvm-1.1.0.1.jar -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Version=1.1.0.1 - -Component.linux_amd64/19.3.0.0/org.graalvm=19.3.0.0/graalvm-19.3.0.0.jar -Component.linux_amd64/19.3.0.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/19.3.0.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/19.3.0.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/19.3.0.0/org.graalvm-Bundle-Version=19.3.0.0 - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog.properties deleted file mode 100644 index 70c3d3a4b590..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog.properties +++ /dev/null @@ -1,103 +0,0 @@ -org.graalvm.1.0.0.0_macos_amd64=GraalVM 1.0.0.0 macos/amd64 -org.graalvm.1.0.0.0_linux_amd64=GraalVM 1.0.1.0 linux/amd64 -org.graalvm.1.0.0-dev_linux_amd64=GraalVM 1.0.0.0-dev linux/amd64 -org.graalvm.1.0.1.0_linux_amd64=GraalVM 1.0.1.1 linux/amd64 -org.graalvm.1.1.0.0_linux_amd64=GraalVM 1.1.0.0 linux/amd64 -org.graalvm.1.1.0.1_linux_amd64=GraalVM 1.1.0.1 linux/amd64 -org.graalvm.1.1.1-0.rc.1_linux_amd64=GraalVM 1.1.0.1 linux/amd64 - -Component.linux_amd64/1.0.0.0/org.graalvm.python=python/1.0.0.0 -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Version=1.0.0.0 - -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm.python=python/1.0.0.0-0.dev -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0-0.dev)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm.python-Bundle-Version=1.0.0.0-0.dev - -Component.linux_amd64/1.0.1.0/org.graalvm.python=python/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.1.0.0/org.graalvm.python=python/1.1.0.0 -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Version=1.1.0.0 - -Component.linux_amd64/1.0.1.0/org.graalvm.r=r/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.1/org.graalvm.r=r/1.0.1.1 -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-Version=1.0.1.1 -Component.linux_amd64/1.1.0.0/org.graalvm.r=r/1.1.0.0 -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-Version=1.1.0.0 -Component.linux_amd64/1.1.0.1/org.graalvm.r=r/1.1.0.1 -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.1)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Version=1.1.0.1 - -Component.linux_amd64/1.0.0.0/org.graalvm.ruby=ruby/1.0.0.0 -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Version=1.0.0.0 -Component.linux_amd64/1.0.1.0/org.graalvm.ruby=ruby/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.1/org.graalvm.ruby=ruby/1.0.1.1 -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-Version=1.0.1.1 - -Component.linux_amd64/1.0.0.0/org.graalvm=core/graalvm-1.0.0.0.jar -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.0.0.0/org.graalvm-Bundle-Version=1.0.0.0 - -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm=core/graalvm-1.0.0.0-0.dev.jar -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.0.0.0-0.dev/org.graalvm-Bundle-Version=1.0.0.0-0.dev - -Component.linux_amd64/1.0.1.0/org.graalvm=core/graalvm-1.0.1.0.jar -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-Version=1.0.1.0 - -Component.linux_amd64/1.1.0.0/org.graalvm=core/graalvm-1.1.0.0.jar -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-Version=1.1.0.0 - -Component.linux_amd64/1.1.0.1/org.graalvm=core/graalvm-1.1.0.1.jar -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Version=1.1.0.1 - -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm=core/graalvm-1.1.1-0.rc.1.jar -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-Version=1.1.1-0.rc.1 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog2.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog2.properties deleted file mode 100644 index 61218e2b9150..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/catalog2.properties +++ /dev/null @@ -1,83 +0,0 @@ -org.graalvm.1.0.0.0_macos_amd64=GraalVM 1.0.0.0 macos/amd64 -org.graalvm.1.0.0.0_linux_amd64=GraalVM 1.0.1.0 linux/amd64 -org.graalvm.1.0.1.0_linux_amd64=GraalVM 1.0.1.1 linux/amd64 -org.graalvm.1.1.0.0_linux_amd64=GraalVM 1.1.0.0 linux/amd64 -org.graalvm.1.1.0.1_linux_amd64=GraalVM 1.1.0.1 linux/amd64 -org.graalvm.1.1.1-0.rc.1_linux_amd64=GraalVM 1.1.0.1 linux/amd64 - -Component.linux_amd64/1.0.0.0/org.graalvm.python=python/1.0.0.0 -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.0.0/org.graalvm.python-Bundle-Version=1.0.0.0 -Component.linux_amd64/1.0.1.0/org.graalvm.python=python/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.0.1.0/org.graalvm.python-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.1.0.0/org.graalvm.python=python/1.1.0.0 -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Symbolic-Name=org.graalvm.python -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Name=Graal.Python -Component.linux_amd64/1.1.0.0/org.graalvm.python-Bundle-Version=1.1.0.0 - -Component.linux_amd64/1.0.1.0/org.graalvm.r=r/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.1.0/org.graalvm.r-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.1/org.graalvm.r=r/1.0.1.1 -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.0.1.1/org.graalvm.r-Bundle-Version=1.0.1.1 -Component.linux_amd64/1.1.0.0/org.graalvm.r=r/1.1.0.0 -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.1.0.0/org.graalvm.r-Bundle-Version=1.1.0.0 -Component.linux_amd64/1.1.0.1/org.graalvm.r=r/1.1.0.1 -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Symbolic-Name=org.graalvm.R -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.1.0.1)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Name=FastR -Component.linux_amd64/1.1.0.1/org.graalvm.r-Bundle-Version=1.1.0.1 - -Component.linux_amd64/1.0.0.0/org.graalvm.ruby=ruby/1.0.0.0 -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.0.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.0.0/org.graalvm.ruby-Bundle-Version=1.0.0.0 -Component.linux_amd64/1.0.1.0/org.graalvm.ruby=ruby/1.0.1.0 -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.1.0/org.graalvm.ruby-Bundle-Version=1.0.1.0 -Component.linux_amd64/1.0.1.1/org.graalvm.ruby=ruby/1.0.1.1 -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-Symbolic-Name=org.graalvm.ruby -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-RequireCapability=org.graalvm; filter:="(&(graalvm_version=1.0.1.0)(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-Name=TruffleRuby -Component.linux_amd64/1.0.1.1/org.graalvm.ruby-Bundle-Version=1.0.1.1 - -Component.linux_amd64/1.0.1.0/org.graalvm=core/graalvm-1.0.1.0.jar -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.0.1.0/org.graalvm-Bundle-Version=1.0.1.0 - -Component.linux_amd64/1.1.0.0/org.graalvm=core/graalvm-1.1.0.0.jar -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.0.0/org.graalvm-Bundle-Version=1.1.0.0 - -Component.linux_amd64/1.1.0.1/org.graalvm=core/graalvm-1.1.0.1.jar -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.0.1/org.graalvm-Bundle-Version=1.1.0.1 - -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm=core/graalvm-1.1.1-0.rc.1.jar -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-Symbolic-Name=org.graalvm -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-RequireCapability=org.graalvm; filter:="(&(os_name=linux)(os_arch=amd64))" -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-Name=GraalVM Core -Component.linux_amd64/1.1.1-0.rc.1/org.graalvm-Bundle-Version=1.1.1-0.rc.1 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.0.1.0.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.0.1.0.jar deleted file mode 100644 index b19647fde2d613a942bd6678d6d7e3cb838c68ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29393 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�^DAkTsyw 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 OzbJt8h$s`p-~JCPx}(Zi%p_SxR6oo{1 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 ICWycN55bwHTmS$7 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.1.1-0.rc.1.jar b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/core/graalvm-1.1.1-0.rc.1.jar deleted file mode 100644 index 33c701cec0e916716d7a13eadab32bf76b03a9cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29378 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. -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/llvm-toolchain/1.1.0.0/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/MANIFEST.MF deleted file mode 100644 index 144f60b09408..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Name: Graal.Python -Bundle-Symbolic-Name: org.graalvm.python -Bundle-Version: 1.0.0.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.0.0.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/python diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/permissions deleted file mode 100644 index c20856a8ebf6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/permissions +++ /dev/null @@ -1,4 +0,0 @@ -jre/languages/python/release = rw-rw-r-- -LICENSE_GRAALPYTHON = rwxrwxrwx -jre/languages/python/README_GRAALPYTHON.md = rw-r--r-- -jre/languages/python/doc/INTEROP.md = rw-r--r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/symlinks deleted file mode 100644 index 6457fbb04174..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/META-INF/symlinks +++ /dev/null @@ -1 +0,0 @@ -LICENSE_GRAALPYTHON = jre/languages/python/LICENSE_GRAALPYTHON diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/LICENSE_GRAALPYTHON b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/LICENSE_GRAALPYTHON deleted file mode 100644 index 773458bc6687..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/LICENSE_GRAALPYTHON +++ /dev/null @@ -1,76 +0,0 @@ -Product License - GraalVM Community Edition 1.0 Python Language -Component - -This is a release of GraalVM Community Edition 1.0 Python Language Component. -This particular copy of the software is released under Universal Permissive -License (UPL) v. 1.0. -Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved - -=========================================================================== - Universal Permissive License v. 1.0. -Copyright (c) 2018, Oracle and/or its affiliates -The Universal Permissive License (UPL), Version 1.0 -Subject to the condition set forth below, permission is hereby granted to any -person obtaining a copy of this software, associated documentation and/or data -(collectively the "Software"), free of charge and under any and all copyright -rights in the Software, and any and all patent rights owned or freely -licensable by each licensor hereunder covering either (i) the unmodified -Software as contributed to or provided by such licensor, or (ii) the Larger -Works (as defined below), to deal in both -(a) the Software, and -(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -one is included with the Software (each a “Larger Work” to which the -Software is contributed by such licensors) -without restriction, including without limitation the rights to copy, create -derivative works of, display, perform, and distribute the Software and make, -use, sell, offer for sale, import, export, have made, and have sold the -Software and the Larger Work(s), and to sublicense the foregoing rights on -either these or other terms. -This license is subject to the following condition: -The above copyright notice and either this complete permission notice or at a -minimum a reference to the UPL must be included in all copies or substantial -portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -=========================================================================== - - WRITTEN OFFER FOR SOURCE CODE -For any software that you receive from Oracle in binary form which is licensed -under an open source license that gives you the right to receive the source -code for that binary, you can obtain a copy of the applicable source code by -visiting http://www.oracle.com/goto/opensourcecode. If the source code for the -binary was not provided to you with the binary, you can also receive a copy of -the source code on physical media by submitting a written request to the -address listed below or by sending an email to Oracle using the following link: - http://www.oracle.com/goto/opensourcecode/request. - -Oracle America, Inc. -Attn: Senior Vice President -Development and Engineering Legal -500 Oracle Parkway, 10th Floor -Redwood Shores, CA 94065 - -Your request should include: - • The name of the binary for which you are requesting the source code - • The name and version number of the Oracle product containing the binary - • The date you received the Oracle product - • Your name - • Your company name (if applicable) - • Your return mailing address and email, and - • A telephone number in the event we need to reach you. - -We may charge you a fee to cover the cost of physical media and processing. -Your request must be sent - a. within three (3) years of the date you received the Oracle product that -included the binary that is the subject of your request, or - b. in the case of code licensed under the GPL v3 for as long as Oracle -offers spare parts or customer support for that product model. - -=========================================================================== - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/doc/INTEROP.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/doc/INTEROP.md deleted file mode 100644 index b687625958c1..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/doc/INTEROP.md +++ /dev/null @@ -1,98 +0,0 @@ -## Interop - -#### Interop from Python - -You can import the `polyglot` module to interact with other languages. - -```python -import polyglot -``` - -You can import a global value from the entire polyglot scope: -```python -imported_polyglot_global = polyglot.import_value("global_name") -``` - -This global should then work as expected; accessing attributes assumes it reads -from the `members` namespace; accessing items is supported both with strings and -numbers; calling methods on the result tries to do a straight invoke and falls -back to reading the member and trying to execute it. - -You can evaluate some code in another language: -```python -polyglot.eval(string="1 + 1", language="ruby") -``` - -It also works with the path to a file: -```python -polyglot.eval(file="./my_ruby_file.rb", language="ruby") -``` - -If you pass a file, you can also try to rely on the file-based language detection: -```python -polyglot.eval(file="./my_ruby_file.rb") -``` - -To export something from Python to other Polyglot languages so they can import -it: -```python -foo = object() -polyglot.export_value(foo, name="python_foo") -``` - -The export function can be used as a decorator, in this case the function name -is used as the globally exported name: -```python -@polyglot.export_value -def python_method(): - return "Hello from Python!" -``` - -Finally, to interoperate with Java (only when running on the JVM), you can use -the `java` module: -```python -import java -BigInteger = java.type("java.math.BigInteger") -myBigInt = BigInteger(42) -myBigInt.shiftLeft(128) # public Java methods can just be called -myBigInt["not"]() # Java method names that are keywords in - # Python can be accessed using "[]" -byteArray = myBigInt.toByteArray() -print(list(byteArray)) # Java arrays can act like Python lists -``` - -For packages under the `java` package, you can also use the normal Python import -syntax: -```python -import java.util.ArrayList -from java.util import ArrayList - -# these are the same class -java.util.ArrayList == ArrayList - -al = ArrayList() -al.add(1) -al.add(12) -print(al) # prints [1, 12] -``` - -In addition to the `type` builtin method, the `java` module, exposes the following -methods as well: - -Builtin | Specification ---- | --- -`instanceof(obj, class)` | returns `True` if `obj` is an instance of `class` (`class` must be a foreign object class) -`is_function(obj)` | returns `True` if `obj` is a Java host language function wrapped using Truffle interop -`is_object(obj)` | returns `True` if `obj` if the argument is Java host language object wrapped using Truffle interop -`is_symbol(obj)` | returns `True` if `obj` if the argument is a Java host symbol, representing the constructor and static members of a Java class, as obtained by `java.type` - -```python -import java -ArrayList = java.type('java.util.ArrayList') -my_list = ArrayList() -print(java.is_symbol(ArrayList)) # prints True -print(java.is_symbol(my_list)) # prints False, my_list is not a Java host symbol -print(java.is_object(ArrayList)) # prints True, symbols are also host objects -print(java.is_function(my_list.add))# prints True, the add method of ArrayList -print(java.instanceof(my_list, ArrayList)) # prints True -``` diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/include/boolobject.h b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/include/boolobject.h deleted file mode 100644 index a93b156a5736..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/include/boolobject.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2018, Oracle and/or its affiliates. - * Copyright (C) 1996-2017 Python Software Foundation - * - * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 - */ -/* Boolean object interface */ - -#ifndef Py_BOOLOBJECT_H -#define Py_BOOLOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_DATA(PyTypeObject) PyBool_Type; - -#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) - -/* Py_False and Py_True are the only two bools in existence. -Don't forget to apply Py_INCREF() when returning either!!! */ - -/* Don't use these directly */ -PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct; - -/* Use these macros */ -#define Py_False ((PyObject *) &_Py_FalseStruct) -#define Py_True ((PyObject *) &_Py_TrueStruct) - -/* Macros for returning Py_True or Py_False, respectively */ -#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False - -/* Function to return a bool from a C long */ -PyAPI_FUNC(PyObject *) PyBool_FromLong(long); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BOOLOBJECT_H */ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-graalpython/_descriptor.py b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-graalpython/_descriptor.py deleted file mode 100644 index 9b0cf58f94e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-graalpython/_descriptor.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -def _f(): pass -FunctionType = type(_f) -descriptor = type(FunctionType.__code__) - - -def make_named_tuple_class(name, fields): - class named_tuple(tuple): - __name__ = name - n_sequence_fields = len(fields) - fields = fields - - def __str__(self): - return self.__repr__() - - def __repr__(self): - sb = [name, "("] - for f in fields: - sb.append(f) - sb.append("=") - sb.append(repr(getattr(self, f))) - sb.append(", ") - sb.pop() - sb.append(")") - return "".join(sb) - - def _define_named_tuple_methods(): - for i, name in enumerate(fields): - def make_func(i): - def func(self): - return self[i] - return func - setattr(named_tuple, name, descriptor(fget=make_func(i), name=name, owner=named_tuple)) - - - _define_named_tuple_methods() - return named_tuple - - -class SimpleNamespace(object): - def __init__(self, **kwargs): - object.__setattr__(self, "__ns__", kwargs) - - def __delattr__(self, name): - object.__getattribute__(self, "__ns__").__delitem__(name) - - def __getattr__(self, name): - return object.__getattribute__(self, "__ns__")[name] - - def __setattr__(self, name, value): - object.__getattribute__(self, "__ns__")[name] = value - - def __repr__(self): - sb = [] - ns = object.__getattribute__(self, "__ns__") - for k,v in ns.items(): - sb.append("%s='%s'" % (k,v)) - return "namespace(%s)" % ", ".join(sb) diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-python/3/_bootlocale.py b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-python/3/_bootlocale.py deleted file mode 100644 index 32987d6942ae..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/lib-python/3/_bootlocale.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""A minimal subset of the locale module used at interpreter startup -(imported by the _io module), in order to reduce startup time. - -Don't import directly from third-party code; use the `locale` module instead! -""" - -import sys -import _locale - -if sys.platform.startswith("win"): - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - return _locale._getdefaultlocale()[1] -else: - try: - _locale.CODESET - except AttributeError: - if hasattr(sys, 'getandroidapilevel'): - # On Android langinfo.h and CODESET are missing, and UTF-8 is - # always used in mbstowcs() and wcstombs(). - def getpreferredencoding(do_setlocale=True): - return 'UTF-8' - else: - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - # This path for legacy systems needs the more complex - # getdefaultlocale() function, import the full locale module. - import locale - return locale.getpreferredencoding(do_setlocale) - else: - def getpreferredencoding(do_setlocale=True): - assert not do_setlocale - if sys.flags.utf8_mode: - return 'UTF-8' - result = _locale.nl_langinfo(_locale.CODESET) - if not result and sys.platform == 'darwin': - # nl_langinfo can return an empty string - # when the setting has an invalid value. - # Default to UTF-8 in that case because - # UTF-8 is the default charset on OSX and - # returning nothing will crash the - # interpreter. - result = 'UTF-8' - return result diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/native-image.properties deleted file mode 100644 index bb816bb158d7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/native-image.properties +++ /dev/null @@ -1,13 +0,0 @@ -# This file contains native-image arguments needed to build graalpython -# - -ImageName = graalpython - -Requires = tool:regex language:llvm - -LauncherClass = com.oracle.graal.python.shell.GraalPythonMain -LauncherClassPath = lib/graalvm/launcher-common.jar:lib/graalvm/graalpython-launcher.jar - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=python - -Args = -H:MaxRuntimeCompileMethods=7000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.0.0/jre/languages/python/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/MANIFEST.MF deleted file mode 100644 index 331bdd6046b6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Name: Graal.Python -Bundle-Symbolic-Name: org.graalvm.python -Bundle-Version: 1.0.1.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.0.1.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/python diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/permissions deleted file mode 100644 index c20856a8ebf6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/permissions +++ /dev/null @@ -1,4 +0,0 @@ -jre/languages/python/release = rw-rw-r-- -LICENSE_GRAALPYTHON = rwxrwxrwx -jre/languages/python/README_GRAALPYTHON.md = rw-r--r-- -jre/languages/python/doc/INTEROP.md = rw-r--r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/symlinks deleted file mode 100644 index 6457fbb04174..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/META-INF/symlinks +++ /dev/null @@ -1 +0,0 @@ -LICENSE_GRAALPYTHON = jre/languages/python/LICENSE_GRAALPYTHON diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/LICENSE_GRAALPYTHON b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/LICENSE_GRAALPYTHON deleted file mode 100644 index 773458bc6687..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/LICENSE_GRAALPYTHON +++ /dev/null @@ -1,76 +0,0 @@ -Product License - GraalVM Community Edition 1.0 Python Language -Component - -This is a release of GraalVM Community Edition 1.0 Python Language Component. -This particular copy of the software is released under Universal Permissive -License (UPL) v. 1.0. -Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved - -=========================================================================== - Universal Permissive License v. 1.0. -Copyright (c) 2018, Oracle and/or its affiliates -The Universal Permissive License (UPL), Version 1.0 -Subject to the condition set forth below, permission is hereby granted to any -person obtaining a copy of this software, associated documentation and/or data -(collectively the "Software"), free of charge and under any and all copyright -rights in the Software, and any and all patent rights owned or freely -licensable by each licensor hereunder covering either (i) the unmodified -Software as contributed to or provided by such licensor, or (ii) the Larger -Works (as defined below), to deal in both -(a) the Software, and -(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -one is included with the Software (each a “Larger Work” to which the -Software is contributed by such licensors) -without restriction, including without limitation the rights to copy, create -derivative works of, display, perform, and distribute the Software and make, -use, sell, offer for sale, import, export, have made, and have sold the -Software and the Larger Work(s), and to sublicense the foregoing rights on -either these or other terms. -This license is subject to the following condition: -The above copyright notice and either this complete permission notice or at a -minimum a reference to the UPL must be included in all copies or substantial -portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -=========================================================================== - - WRITTEN OFFER FOR SOURCE CODE -For any software that you receive from Oracle in binary form which is licensed -under an open source license that gives you the right to receive the source -code for that binary, you can obtain a copy of the applicable source code by -visiting http://www.oracle.com/goto/opensourcecode. If the source code for the -binary was not provided to you with the binary, you can also receive a copy of -the source code on physical media by submitting a written request to the -address listed below or by sending an email to Oracle using the following link: - http://www.oracle.com/goto/opensourcecode/request. - -Oracle America, Inc. -Attn: Senior Vice President -Development and Engineering Legal -500 Oracle Parkway, 10th Floor -Redwood Shores, CA 94065 - -Your request should include: - • The name of the binary for which you are requesting the source code - • The name and version number of the Oracle product containing the binary - • The date you received the Oracle product - • Your name - • Your company name (if applicable) - • Your return mailing address and email, and - • A telephone number in the event we need to reach you. - -We may charge you a fee to cover the cost of physical media and processing. -Your request must be sent - a. within three (3) years of the date you received the Oracle product that -included the binary that is the subject of your request, or - b. in the case of code licensed under the GPL v3 for as long as Oracle -offers spare parts or customer support for that product model. - -=========================================================================== - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/doc/INTEROP.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/doc/INTEROP.md deleted file mode 100644 index b687625958c1..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/doc/INTEROP.md +++ /dev/null @@ -1,98 +0,0 @@ -## Interop - -#### Interop from Python - -You can import the `polyglot` module to interact with other languages. - -```python -import polyglot -``` - -You can import a global value from the entire polyglot scope: -```python -imported_polyglot_global = polyglot.import_value("global_name") -``` - -This global should then work as expected; accessing attributes assumes it reads -from the `members` namespace; accessing items is supported both with strings and -numbers; calling methods on the result tries to do a straight invoke and falls -back to reading the member and trying to execute it. - -You can evaluate some code in another language: -```python -polyglot.eval(string="1 + 1", language="ruby") -``` - -It also works with the path to a file: -```python -polyglot.eval(file="./my_ruby_file.rb", language="ruby") -``` - -If you pass a file, you can also try to rely on the file-based language detection: -```python -polyglot.eval(file="./my_ruby_file.rb") -``` - -To export something from Python to other Polyglot languages so they can import -it: -```python -foo = object() -polyglot.export_value(foo, name="python_foo") -``` - -The export function can be used as a decorator, in this case the function name -is used as the globally exported name: -```python -@polyglot.export_value -def python_method(): - return "Hello from Python!" -``` - -Finally, to interoperate with Java (only when running on the JVM), you can use -the `java` module: -```python -import java -BigInteger = java.type("java.math.BigInteger") -myBigInt = BigInteger(42) -myBigInt.shiftLeft(128) # public Java methods can just be called -myBigInt["not"]() # Java method names that are keywords in - # Python can be accessed using "[]" -byteArray = myBigInt.toByteArray() -print(list(byteArray)) # Java arrays can act like Python lists -``` - -For packages under the `java` package, you can also use the normal Python import -syntax: -```python -import java.util.ArrayList -from java.util import ArrayList - -# these are the same class -java.util.ArrayList == ArrayList - -al = ArrayList() -al.add(1) -al.add(12) -print(al) # prints [1, 12] -``` - -In addition to the `type` builtin method, the `java` module, exposes the following -methods as well: - -Builtin | Specification ---- | --- -`instanceof(obj, class)` | returns `True` if `obj` is an instance of `class` (`class` must be a foreign object class) -`is_function(obj)` | returns `True` if `obj` is a Java host language function wrapped using Truffle interop -`is_object(obj)` | returns `True` if `obj` if the argument is Java host language object wrapped using Truffle interop -`is_symbol(obj)` | returns `True` if `obj` if the argument is a Java host symbol, representing the constructor and static members of a Java class, as obtained by `java.type` - -```python -import java -ArrayList = java.type('java.util.ArrayList') -my_list = ArrayList() -print(java.is_symbol(ArrayList)) # prints True -print(java.is_symbol(my_list)) # prints False, my_list is not a Java host symbol -print(java.is_object(ArrayList)) # prints True, symbols are also host objects -print(java.is_function(my_list.add))# prints True, the add method of ArrayList -print(java.instanceof(my_list, ArrayList)) # prints True -``` diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/include/boolobject.h b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/include/boolobject.h deleted file mode 100644 index a93b156a5736..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/include/boolobject.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2018, Oracle and/or its affiliates. - * Copyright (C) 1996-2017 Python Software Foundation - * - * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 - */ -/* Boolean object interface */ - -#ifndef Py_BOOLOBJECT_H -#define Py_BOOLOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_DATA(PyTypeObject) PyBool_Type; - -#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) - -/* Py_False and Py_True are the only two bools in existence. -Don't forget to apply Py_INCREF() when returning either!!! */ - -/* Don't use these directly */ -PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct; - -/* Use these macros */ -#define Py_False ((PyObject *) &_Py_FalseStruct) -#define Py_True ((PyObject *) &_Py_TrueStruct) - -/* Macros for returning Py_True or Py_False, respectively */ -#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False - -/* Function to return a bool from a C long */ -PyAPI_FUNC(PyObject *) PyBool_FromLong(long); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BOOLOBJECT_H */ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-graalpython/_descriptor.py b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-graalpython/_descriptor.py deleted file mode 100644 index 9b0cf58f94e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-graalpython/_descriptor.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -def _f(): pass -FunctionType = type(_f) -descriptor = type(FunctionType.__code__) - - -def make_named_tuple_class(name, fields): - class named_tuple(tuple): - __name__ = name - n_sequence_fields = len(fields) - fields = fields - - def __str__(self): - return self.__repr__() - - def __repr__(self): - sb = [name, "("] - for f in fields: - sb.append(f) - sb.append("=") - sb.append(repr(getattr(self, f))) - sb.append(", ") - sb.pop() - sb.append(")") - return "".join(sb) - - def _define_named_tuple_methods(): - for i, name in enumerate(fields): - def make_func(i): - def func(self): - return self[i] - return func - setattr(named_tuple, name, descriptor(fget=make_func(i), name=name, owner=named_tuple)) - - - _define_named_tuple_methods() - return named_tuple - - -class SimpleNamespace(object): - def __init__(self, **kwargs): - object.__setattr__(self, "__ns__", kwargs) - - def __delattr__(self, name): - object.__getattribute__(self, "__ns__").__delitem__(name) - - def __getattr__(self, name): - return object.__getattribute__(self, "__ns__")[name] - - def __setattr__(self, name, value): - object.__getattribute__(self, "__ns__")[name] = value - - def __repr__(self): - sb = [] - ns = object.__getattribute__(self, "__ns__") - for k,v in ns.items(): - sb.append("%s='%s'" % (k,v)) - return "namespace(%s)" % ", ".join(sb) diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-python/3/_bootlocale.py b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-python/3/_bootlocale.py deleted file mode 100644 index 32987d6942ae..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/lib-python/3/_bootlocale.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""A minimal subset of the locale module used at interpreter startup -(imported by the _io module), in order to reduce startup time. - -Don't import directly from third-party code; use the `locale` module instead! -""" - -import sys -import _locale - -if sys.platform.startswith("win"): - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - return _locale._getdefaultlocale()[1] -else: - try: - _locale.CODESET - except AttributeError: - if hasattr(sys, 'getandroidapilevel'): - # On Android langinfo.h and CODESET are missing, and UTF-8 is - # always used in mbstowcs() and wcstombs(). - def getpreferredencoding(do_setlocale=True): - return 'UTF-8' - else: - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - # This path for legacy systems needs the more complex - # getdefaultlocale() function, import the full locale module. - import locale - return locale.getpreferredencoding(do_setlocale) - else: - def getpreferredencoding(do_setlocale=True): - assert not do_setlocale - if sys.flags.utf8_mode: - return 'UTF-8' - result = _locale.nl_langinfo(_locale.CODESET) - if not result and sys.platform == 'darwin': - # nl_langinfo can return an empty string - # when the setting has an invalid value. - # Default to UTF-8 in that case because - # UTF-8 is the default charset on OSX and - # returning nothing will crash the - # interpreter. - result = 'UTF-8' - return result diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/native-image.properties deleted file mode 100644 index 2492501f8012..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/native-image.properties +++ /dev/null @@ -1,13 +0,0 @@ -# This file contains native-image arguments needed to build graalpython -# - -ImageName = graalpython - -Requires = tool:regex language:llvm - -LauncherClass = com.oracle.graal.python.shell.GraalPythonMain -LauncherClassPath = lib/graalvm/launcher-common.jar:lib/graalvm/graalpython-launcher.jar - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=python - -Args = -H:MaxRuntimeCompileMethods=7000 \ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.0.1.0/jre/languages/python/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/MANIFEST.MF deleted file mode 100644 index eaf3354efcf8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,6 +0,0 @@ -Bundle-Name: Graal.Python -Bundle-Symbolic-Name: org.graalvm.python -Bundle-Version: 1.1.0.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.1.0.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/python diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/permissions deleted file mode 100644 index c20856a8ebf6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/permissions +++ /dev/null @@ -1,4 +0,0 @@ -jre/languages/python/release = rw-rw-r-- -LICENSE_GRAALPYTHON = rwxrwxrwx -jre/languages/python/README_GRAALPYTHON.md = rw-r--r-- -jre/languages/python/doc/INTEROP.md = rw-r--r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/symlinks deleted file mode 100644 index 6457fbb04174..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/META-INF/symlinks +++ /dev/null @@ -1 +0,0 @@ -LICENSE_GRAALPYTHON = jre/languages/python/LICENSE_GRAALPYTHON diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/LICENSE_GRAALPYTHON b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/LICENSE_GRAALPYTHON deleted file mode 100644 index 773458bc6687..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/LICENSE_GRAALPYTHON +++ /dev/null @@ -1,76 +0,0 @@ -Product License - GraalVM Community Edition 1.0 Python Language -Component - -This is a release of GraalVM Community Edition 1.0 Python Language Component. -This particular copy of the software is released under Universal Permissive -License (UPL) v. 1.0. -Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved - -=========================================================================== - Universal Permissive License v. 1.0. -Copyright (c) 2018, Oracle and/or its affiliates -The Universal Permissive License (UPL), Version 1.0 -Subject to the condition set forth below, permission is hereby granted to any -person obtaining a copy of this software, associated documentation and/or data -(collectively the "Software"), free of charge and under any and all copyright -rights in the Software, and any and all patent rights owned or freely -licensable by each licensor hereunder covering either (i) the unmodified -Software as contributed to or provided by such licensor, or (ii) the Larger -Works (as defined below), to deal in both -(a) the Software, and -(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -one is included with the Software (each a “Larger Work” to which the -Software is contributed by such licensors) -without restriction, including without limitation the rights to copy, create -derivative works of, display, perform, and distribute the Software and make, -use, sell, offer for sale, import, export, have made, and have sold the -Software and the Larger Work(s), and to sublicense the foregoing rights on -either these or other terms. -This license is subject to the following condition: -The above copyright notice and either this complete permission notice or at a -minimum a reference to the UPL must be included in all copies or substantial -portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -=========================================================================== - - WRITTEN OFFER FOR SOURCE CODE -For any software that you receive from Oracle in binary form which is licensed -under an open source license that gives you the right to receive the source -code for that binary, you can obtain a copy of the applicable source code by -visiting http://www.oracle.com/goto/opensourcecode. If the source code for the -binary was not provided to you with the binary, you can also receive a copy of -the source code on physical media by submitting a written request to the -address listed below or by sending an email to Oracle using the following link: - http://www.oracle.com/goto/opensourcecode/request. - -Oracle America, Inc. -Attn: Senior Vice President -Development and Engineering Legal -500 Oracle Parkway, 10th Floor -Redwood Shores, CA 94065 - -Your request should include: - • The name of the binary for which you are requesting the source code - • The name and version number of the Oracle product containing the binary - • The date you received the Oracle product - • Your name - • Your company name (if applicable) - • Your return mailing address and email, and - • A telephone number in the event we need to reach you. - -We may charge you a fee to cover the cost of physical media and processing. -Your request must be sent - a. within three (3) years of the date you received the Oracle product that -included the binary that is the subject of your request, or - b. in the case of code licensed under the GPL v3 for as long as Oracle -offers spare parts or customer support for that product model. - -=========================================================================== - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/doc/INTEROP.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/doc/INTEROP.md deleted file mode 100644 index b687625958c1..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/doc/INTEROP.md +++ /dev/null @@ -1,98 +0,0 @@ -## Interop - -#### Interop from Python - -You can import the `polyglot` module to interact with other languages. - -```python -import polyglot -``` - -You can import a global value from the entire polyglot scope: -```python -imported_polyglot_global = polyglot.import_value("global_name") -``` - -This global should then work as expected; accessing attributes assumes it reads -from the `members` namespace; accessing items is supported both with strings and -numbers; calling methods on the result tries to do a straight invoke and falls -back to reading the member and trying to execute it. - -You can evaluate some code in another language: -```python -polyglot.eval(string="1 + 1", language="ruby") -``` - -It also works with the path to a file: -```python -polyglot.eval(file="./my_ruby_file.rb", language="ruby") -``` - -If you pass a file, you can also try to rely on the file-based language detection: -```python -polyglot.eval(file="./my_ruby_file.rb") -``` - -To export something from Python to other Polyglot languages so they can import -it: -```python -foo = object() -polyglot.export_value(foo, name="python_foo") -``` - -The export function can be used as a decorator, in this case the function name -is used as the globally exported name: -```python -@polyglot.export_value -def python_method(): - return "Hello from Python!" -``` - -Finally, to interoperate with Java (only when running on the JVM), you can use -the `java` module: -```python -import java -BigInteger = java.type("java.math.BigInteger") -myBigInt = BigInteger(42) -myBigInt.shiftLeft(128) # public Java methods can just be called -myBigInt["not"]() # Java method names that are keywords in - # Python can be accessed using "[]" -byteArray = myBigInt.toByteArray() -print(list(byteArray)) # Java arrays can act like Python lists -``` - -For packages under the `java` package, you can also use the normal Python import -syntax: -```python -import java.util.ArrayList -from java.util import ArrayList - -# these are the same class -java.util.ArrayList == ArrayList - -al = ArrayList() -al.add(1) -al.add(12) -print(al) # prints [1, 12] -``` - -In addition to the `type` builtin method, the `java` module, exposes the following -methods as well: - -Builtin | Specification ---- | --- -`instanceof(obj, class)` | returns `True` if `obj` is an instance of `class` (`class` must be a foreign object class) -`is_function(obj)` | returns `True` if `obj` is a Java host language function wrapped using Truffle interop -`is_object(obj)` | returns `True` if `obj` if the argument is Java host language object wrapped using Truffle interop -`is_symbol(obj)` | returns `True` if `obj` if the argument is a Java host symbol, representing the constructor and static members of a Java class, as obtained by `java.type` - -```python -import java -ArrayList = java.type('java.util.ArrayList') -my_list = ArrayList() -print(java.is_symbol(ArrayList)) # prints True -print(java.is_symbol(my_list)) # prints False, my_list is not a Java host symbol -print(java.is_object(ArrayList)) # prints True, symbols are also host objects -print(java.is_function(my_list.add))# prints True, the add method of ArrayList -print(java.instanceof(my_list, ArrayList)) # prints True -``` diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/include/boolobject.h b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/include/boolobject.h deleted file mode 100644 index a93b156a5736..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/include/boolobject.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2018, Oracle and/or its affiliates. - * Copyright (C) 1996-2017 Python Software Foundation - * - * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 - */ -/* Boolean object interface */ - -#ifndef Py_BOOLOBJECT_H -#define Py_BOOLOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -PyAPI_DATA(PyTypeObject) PyBool_Type; - -#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) - -/* Py_False and Py_True are the only two bools in existence. -Don't forget to apply Py_INCREF() when returning either!!! */ - -/* Don't use these directly */ -PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct; - -/* Use these macros */ -#define Py_False ((PyObject *) &_Py_FalseStruct) -#define Py_True ((PyObject *) &_Py_TrueStruct) - -/* Macros for returning Py_True or Py_False, respectively */ -#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True -#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False - -/* Function to return a bool from a C long */ -PyAPI_FUNC(PyObject *) PyBool_FromLong(long); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_BOOLOBJECT_H */ diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-graalpython/_descriptor.py b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-graalpython/_descriptor.py deleted file mode 100644 index 9b0cf58f94e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-graalpython/_descriptor.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -def _f(): pass -FunctionType = type(_f) -descriptor = type(FunctionType.__code__) - - -def make_named_tuple_class(name, fields): - class named_tuple(tuple): - __name__ = name - n_sequence_fields = len(fields) - fields = fields - - def __str__(self): - return self.__repr__() - - def __repr__(self): - sb = [name, "("] - for f in fields: - sb.append(f) - sb.append("=") - sb.append(repr(getattr(self, f))) - sb.append(", ") - sb.pop() - sb.append(")") - return "".join(sb) - - def _define_named_tuple_methods(): - for i, name in enumerate(fields): - def make_func(i): - def func(self): - return self[i] - return func - setattr(named_tuple, name, descriptor(fget=make_func(i), name=name, owner=named_tuple)) - - - _define_named_tuple_methods() - return named_tuple - - -class SimpleNamespace(object): - def __init__(self, **kwargs): - object.__setattr__(self, "__ns__", kwargs) - - def __delattr__(self, name): - object.__getattribute__(self, "__ns__").__delitem__(name) - - def __getattr__(self, name): - return object.__getattribute__(self, "__ns__")[name] - - def __setattr__(self, name, value): - object.__getattribute__(self, "__ns__")[name] = value - - def __repr__(self): - sb = [] - ns = object.__getattribute__(self, "__ns__") - for k,v in ns.items(): - sb.append("%s='%s'" % (k,v)) - return "namespace(%s)" % ", ".join(sb) diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-python/3/_bootlocale.py b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-python/3/_bootlocale.py deleted file mode 100644 index 32987d6942ae..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/lib-python/3/_bootlocale.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# The Universal Permissive License (UPL), Version 1.0 -# -# Subject to the condition set forth below, permission is hereby granted to any -# person obtaining a copy of this software, associated documentation and/or -# data (collectively the "Software"), free of charge and under any and all -# copyright rights in the Software, and any and all patent rights owned or -# freely licensable by each licensor hereunder covering either (i) the -# unmodified Software as contributed to or provided by such licensor, or (ii) -# the Larger Works (as defined below), to deal in both -# -# (a) the Software, and -# -# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if -# one is included with the Software each a "Larger Work" to which the Software -# is contributed by such licensors), -# -# without restriction, including without limitation the rights to copy, create -# derivative works of, display, perform, and distribute the Software and make, -# use, sell, offer for sale, import, export, have made, and have sold the -# Software and the Larger Work(s), and to sublicense the foregoing rights on -# either these or other terms. -# -# This license is subject to the following condition: -# -# The above copyright notice and either this complete permission notice or at a -# minimum a reference to the UPL must be included in all copies or substantial -# portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""A minimal subset of the locale module used at interpreter startup -(imported by the _io module), in order to reduce startup time. - -Don't import directly from third-party code; use the `locale` module instead! -""" - -import sys -import _locale - -if sys.platform.startswith("win"): - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - return _locale._getdefaultlocale()[1] -else: - try: - _locale.CODESET - except AttributeError: - if hasattr(sys, 'getandroidapilevel'): - # On Android langinfo.h and CODESET are missing, and UTF-8 is - # always used in mbstowcs() and wcstombs(). - def getpreferredencoding(do_setlocale=True): - return 'UTF-8' - else: - def getpreferredencoding(do_setlocale=True): - if sys.flags.utf8_mode: - return 'UTF-8' - # This path for legacy systems needs the more complex - # getdefaultlocale() function, import the full locale module. - import locale - return locale.getpreferredencoding(do_setlocale) - else: - def getpreferredencoding(do_setlocale=True): - assert not do_setlocale - if sys.flags.utf8_mode: - return 'UTF-8' - result = _locale.nl_langinfo(_locale.CODESET) - if not result and sys.platform == 'darwin': - # nl_langinfo can return an empty string - # when the setting has an invalid value. - # Default to UTF-8 in that case because - # UTF-8 is the default charset on OSX and - # returning nothing will crash the - # interpreter. - result = 'UTF-8' - return result diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/native-image.properties deleted file mode 100644 index bb816bb158d7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/native-image.properties +++ /dev/null @@ -1,13 +0,0 @@ -# This file contains native-image arguments needed to build graalpython -# - -ImageName = graalpython - -Requires = tool:regex language:llvm - -LauncherClass = com.oracle.graal.python.shell.GraalPythonMain -LauncherClassPath = lib/graalvm/launcher-common.jar:lib/graalvm/graalpython-launcher.jar - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=python - -Args = -H:MaxRuntimeCompileMethods=7000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/python/1.1.0.0/jre/languages/python/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/MANIFEST.MF deleted file mode 100644 index f995326cd3fa..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,24 +0,0 @@ -Bundle-Name: FastR -Bundle-Symbolic-Name: org.graalvm.R -Bundle-Version: 1.0.1.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.0.1.0 - )(os_name=macos)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/R -x-GraalVM-Message-PostInst: NOTES:\n---------------\nSome R packages nee - d a system-dependent configuration before they can be installed. A gener - ic configuration that works out of the box in most cases is provided by - default. If you wish to fine-tune the configuration to your system or sh - ould you encounter any issues during R package installation, try running - the following script that adjusts the configuration to your system: \n - ${graalvm_home}/jre/languages/R/bin/configure_fastr\n\nThe R componen - t comes without native image by default. If you wish to build the native - image, which provides faster startup, but slightly slower peak performa - nce, then run the following:\n ${graalvm_home}/jre/languages/R/bin/ins - tall_r_native_image\n\nThe native image is then used by default. Pass '- - -jvm' flag to the R or Rscript launcher to use JVM instead of the native - image. Note that the native image is not stable yet and is intended for - evaluation purposes and experiments. Some features may not work when th - e native image is installed, most notably the --polyglot switch. The nat - ive image can be uninstalled using the installation script with 'uninsta - ll' argument.\n\nSee http://www.graalvm.org/docs/reference-manual/langua - ges/r for more. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/permissions deleted file mode 100644 index 14fe1475669d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/permissions +++ /dev/null @@ -1,1622 +0,0 @@ -jre/languages/R/bin/R = rwxr-xr-x -jre/languages/R/bin/Rdconv = rwxr-xr-x -jre/languages/R/bin/SHLIB = rwxr-xr-x -jre/languages/R/bin/COMPILE = rwxr-xr-x -jre/languages/R/bin/LINK = rwxr-xr-x -jre/languages/R/bin/Sweave = rwxr-xr-x -jre/languages/R/bin/BATCH = rwxr-xr-x -jre/languages/R/bin/install_r_native_image = rwxr-xr-x -jre/languages/R/bin/f77_f2c = rwxr-xr-x -jre/languages/R/bin/build = rwxr-xr-x -jre/languages/R/bin/mkinstalldirs = rwxr-xr-x -jre/languages/R/bin/Rdiff = rwxr-xr-x -jre/languages/R/bin/check = rwxr-xr-x -jre/languages/R/bin/Stangle = rwxr-xr-x -jre/languages/R/bin/pager = rwxr-xr-x -jre/languages/R/include/S.h = rw-r--r-- -jre/languages/R/include/Rinternals.h = rw-r--r-- -jre/languages/R/include/Makefile = rw-r--r-- -jre/languages/R/include/Rembedded.h = rw-r--r-- -jre/languages/R/include/Rconfig.h = rw-r--r-- -jre/languages/R/include/Rdefines.h = rw-r--r-- -jre/languages/R/include/linked = rw-r--r-- -jre/languages/R/include/Rmath.h = rw-r--r-- -jre/languages/R/include/R.h = rw-r--r-- -jre/languages/R/include/Rversion.h = rw-r--r-- -jre/languages/R/include/Rinterface.h = rw-r--r-- -jre/languages/R/include/R_ext/GraphicsEngine.h = rw-r--r-- -jre/languages/R/include/R_ext/R-ftp-http.h = rw-r--r-- -jre/languages/R/include/R_ext/Error.h = rw-r--r-- -jre/languages/R/include/R_ext/Itermacros.h = rw-r--r-- -jre/languages/R/include/R_ext/Utils.h = rw-r--r-- -jre/languages/R/include/R_ext/stats_stubs.h = rw-r--r-- -jre/languages/R/include/R_ext/GetX11Image.h = rw-r--r-- -jre/languages/R/include/R_ext/GraphicsDevice.h = rw-r--r-- -jre/languages/R/include/R_ext/Callbacks.h = rw-r--r-- -jre/languages/R/include/R_ext/Rdynload.h = rw-r--r-- -jre/languages/R/include/R_ext/Parse.h = rw-r--r-- -jre/languages/R/include/R_ext/RS.h = rw-r--r-- -jre/languages/R/include/R_ext/BLAS.h = rw-r--r-- -jre/languages/R/include/R_ext/Arith.h = rw-r--r-- -jre/languages/R/include/R_ext/Boolean.h = rw-r--r-- -jre/languages/R/include/R_ext/Applic.h = rw-r--r-- -jre/languages/R/include/R_ext/Linpack.h = rw-r--r-- -jre/languages/R/include/R_ext/Constants.h = rw-r--r-- -jre/languages/R/include/R_ext/Riconv.h = rw-r--r-- -jre/languages/R/include/R_ext/RStartup.h = rw-r--r-- -jre/languages/R/include/R_ext/Print.h = rw-r--r-- -jre/languages/R/include/R_ext/QuartzDevice.h = rw-r--r-- -jre/languages/R/include/R_ext/libextern.h = rw-r--r-- -jre/languages/R/include/R_ext/MathThreads.h = rw-r--r-- -jre/languages/R/include/R_ext/Memory.h = rw-r--r-- -jre/languages/R/include/R_ext/Connections.h = rw-r--r-- -jre/languages/R/include/R_ext/PrtUtil.h = rw-r--r-- -jre/languages/R/include/R_ext/Altrep.h = rw-r--r-- -jre/languages/R/include/R_ext/Rallocators.h = rw-r--r-- -jre/languages/R/include/R_ext/Visibility.h = rw-r--r-- -jre/languages/R/include/R_ext/stats_package.h = rw-r--r-- -jre/languages/R/include/R_ext/Complex.h = rw-r--r-- -jre/languages/R/include/R_ext/Lapack.h = rw-r--r-- -jre/languages/R/include/R_ext/Random.h = rw-r--r-- -jre/languages/R/include/R_ext/eventloop.h = rw-r--r-- -jre/languages/R/lib/libgfortran.dylib = rwxrwxrwx -jre/languages/R/lib/libz.dylib = rwxrwxrwx -jre/languages/R/lib/libpcre.1.dylib = rw-r--r-- -jre/languages/R/lib/libRblas.dylib = rwxr-xr-x -jre/languages/R/lib/libpcre.dylib = rwxrwxrwx -jre/languages/R/lib/libgfortran.3.dylib = rw-r--r-- -jre/languages/R/lib/libgcc_s.dylib = rwxrwxrwx -jre/languages/R/lib/libR.dylib = rwxr-xr-x -jre/languages/R/lib/libquadmath.0.dylib = rw-r--r-- -jre/languages/R/lib/libz.1.dylib = rw-r--r-- -jre/languages/R/lib/libgcc_s.1.dylib = rw-r--r-- -jre/languages/R/lib/libRlapack.dylib = rwxr-xr-x -jre/languages/R/lib/libquadmath.dylib = rwxrwxrwx -jre/languages/R/library/MASS/CITATION = rw-r--r-- -jre/languages/R/library/MASS/NAMESPACE = rw-r--r-- -jre/languages/R/library/MASS/DESCRIPTION = rw-r--r-- -jre/languages/R/library/MASS/NEWS = rw-r--r-- -jre/languages/R/library/MASS/INDEX = rw-r--r-- -jre/languages/R/library/MASS/R/profiles.R = rw-r--r-- -jre/languages/R/library/MASS/R/write.matrix.R = rw-r--r-- -jre/languages/R/library/MASS/R/MASS.rdx = rw-r--r-- -jre/languages/R/library/MASS/R/corresp.R = rw-r--r-- -jre/languages/R/library/MASS/R/fitdistr.R = rw-r--r-- -jre/languages/R/library/MASS/R/sammon.R = rw-r--r-- -jre/languages/R/library/MASS/R/logtrans.R = rw-r--r-- -jre/languages/R/library/MASS/R/MASS = rw-r--r-- -jre/languages/R/library/MASS/R/MASS.rdb = rw-r--r-- -jre/languages/R/library/MASS/R/dose.p.R = rw-r--r-- -jre/languages/R/library/MASS/R/stdres.R = rw-r--r-- -jre/languages/R/library/MASS/R/enlist.R = rw-r--r-- -jre/languages/R/library/MASS/R/add.R = rw-r--r-- -jre/languages/R/library/MASS/R/neg.bin.R = rw-r--r-- -jre/languages/R/library/MASS/R/contr.sdif.R = rw-r--r-- -jre/languages/R/library/MASS/R/misc.R = rw-r--r-- -jre/languages/R/library/MASS/R/cov.trob.R = rw-r--r-- -jre/languages/R/library/MASS/R/polr.R = rw-r--r-- -jre/languages/R/library/MASS/R/hist.scott.R = rw-r--r-- -jre/languages/R/library/MASS/R/lda.R = rw-r--r-- -jre/languages/R/library/MASS/R/stepAIC.R = rw-r--r-- -jre/languages/R/library/MASS/R/area.R = rw-r--r-- -jre/languages/R/library/MASS/R/rms.curv.R = rw-r--r-- -jre/languages/R/library/MASS/R/fractions.R = rw-r--r-- -jre/languages/R/library/MASS/R/eqscplot.R = rw-r--r-- -jre/languages/R/library/MASS/R/kde2d.R = rw-r--r-- -jre/languages/R/library/MASS/R/lm.ridge.R = rw-r--r-- -jre/languages/R/library/MASS/R/confint.R = rw-r--r-- -jre/languages/R/library/MASS/R/ucv.R = rw-r--r-- -jre/languages/R/library/MASS/R/loglm.R = rw-r--r-- -jre/languages/R/library/MASS/R/gamma.shape.R = rw-r--r-- -jre/languages/R/library/MASS/R/negexp.R = rw-r--r-- -jre/languages/R/library/MASS/R/mca.R = rw-r--r-- -jre/languages/R/library/MASS/R/rlm.R = rw-r--r-- -jre/languages/R/library/MASS/R/truehist.R = rw-r--r-- -jre/languages/R/library/MASS/R/negbin.R = rw-r--r-- -jre/languages/R/library/MASS/R/qda.R = rw-r--r-- -jre/languages/R/library/MASS/R/huber.R = rw-r--r-- -jre/languages/R/library/MASS/R/mvrnorm.R = rw-r--r-- -jre/languages/R/library/MASS/R/zzz.R = rw-r--r-- -jre/languages/R/library/MASS/R/boxcox.R = rw-r--r-- -jre/languages/R/library/MASS/R/lm.gls.R = rw-r--r-- -jre/languages/R/library/MASS/R/parcoord.R = rw-r--r-- -jre/languages/R/library/MASS/R/glmmPQL.R = rw-r--r-- -jre/languages/R/library/MASS/R/isoMDS.R = rw-r--r-- -jre/languages/R/library/MASS/R/hubers.R = rw-r--r-- -jre/languages/R/library/MASS/R/lqs.R = rw-r--r-- -jre/languages/R/library/MASS/Meta/data.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/links.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/features.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/package.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/MASS/html/R.css = rw-r--r-- -jre/languages/R/library/MASS/html/00Index.html = rw-r--r-- -jre/languages/R/library/MASS/libs/MASS.so = rwxr-xr-x -jre/languages/R/library/MASS/po/pl/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/en@quot/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/de/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/ko/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/fr/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch13.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch07.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch09.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch03.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch10.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch14.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch04.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch11.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch15.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch05.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch01.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch12.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch16.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch06.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch02.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch08.R = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/MASS/help/MASS.rdx = rw-r--r-- -jre/languages/R/library/MASS/help/MASS.rdb = rw-r--r-- -jre/languages/R/library/MASS/help/AnIndex = rw-r--r-- -jre/languages/R/library/MASS/help/aliases.rds = rw-r--r-- -jre/languages/R/library/MASS/help/paths.rds = rw-r--r-- -jre/languages/R/library/cluster/CITATION = rw-r--r-- -jre/languages/R/library/cluster/NEWS.Rd = rw-r--r-- -jre/languages/R/library/cluster/NAMESPACE = rw-r--r-- -jre/languages/R/library/cluster/DESCRIPTION = rw-r--r-- -jre/languages/R/library/cluster/INDEX = rw-r--r-- -jre/languages/R/library/cluster/test-tools.R = rw-r--r-- -jre/languages/R/library/cluster/R/internal.R = rw-r--r-- -jre/languages/R/library/cluster/R/clusGapGen.R = rw-r--r-- -jre/languages/R/library/cluster/R/0aaa.R = rw-r--r-- -jre/languages/R/library/cluster/R/cluster.rdb = rw-r--r-- -jre/languages/R/library/cluster/R/cluster.rdx = rw-r--r-- -jre/languages/R/library/cluster/R/cluster = rw-r--r-- -jre/languages/R/library/cluster/R/coef.R = rw-r--r-- -jre/languages/R/library/cluster/R/clara.q = rw-r--r-- -jre/languages/R/library/cluster/R/silhouette.R = rw-r--r-- -jre/languages/R/library/cluster/R/mona.q = rw-r--r-- -jre/languages/R/library/cluster/R/pam.q = rw-r--r-- -jre/languages/R/library/cluster/R/plothier.q = rw-r--r-- -jre/languages/R/library/cluster/R/fanny.q = rw-r--r-- -jre/languages/R/library/cluster/R/plotpart.q = rw-r--r-- -jre/languages/R/library/cluster/R/daisy.q = rw-r--r-- -jre/languages/R/library/cluster/R/clusGap.R = rw-r--r-- -jre/languages/R/library/cluster/R/zzz.R = rw-r--r-- -jre/languages/R/library/cluster/R/ellipsoidhull.R = rw-r--r-- -jre/languages/R/library/cluster/R/diana.q = rw-r--r-- -jre/languages/R/library/cluster/R/agnes.q = rw-r--r-- -jre/languages/R/library/cluster/Meta/data.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/links.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/features.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/package.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/cluster/html/R.css = rw-r--r-- -jre/languages/R/library/cluster/html/00Index.html = rw-r--r-- -jre/languages/R/library/cluster/libs/cluster.so = rwxr-xr-x -jre/languages/R/library/cluster/po/pl/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/en@quot/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/en@quot/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/de/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/de/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/ko/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/ko/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/fr/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/cluster/help/cluster.rdb = rw-r--r-- -jre/languages/R/library/cluster/help/cluster.rdx = rw-r--r-- -jre/languages/R/library/cluster/help/AnIndex = rw-r--r-- -jre/languages/R/library/cluster/help/aliases.rds = rw-r--r-- -jre/languages/R/library/cluster/help/paths.rds = rw-r--r-- -jre/languages/R/library/parallel/NAMESPACE = rw-r--r-- -jre/languages/R/library/parallel/DESCRIPTION = rw-r--r-- -jre/languages/R/library/parallel/INDEX = rw-r--r-- -jre/languages/R/library/parallel/R/parallel = rw-r--r-- -jre/languages/R/library/parallel/R/parallel.rdx = rw-r--r-- -jre/languages/R/library/parallel/R/parallel.rdb = rw-r--r-- -jre/languages/R/library/parallel/Meta/links.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/features.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/package.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/parallel/html/R.css = rw-r--r-- -jre/languages/R/library/parallel/html/00Index.html = rw-r--r-- -jre/languages/R/library/parallel/libs/parallel.so = rwxr-xr-x -jre/languages/R/library/parallel/doc/parallel.pdf = rw-r--r-- -jre/languages/R/library/parallel/help/AnIndex = rw-r--r-- -jre/languages/R/library/parallel/help/aliases.rds = rw-r--r-- -jre/languages/R/library/parallel/help/paths.rds = rw-r--r-- -jre/languages/R/library/parallel/help/parallel.rdx = rw-r--r-- -jre/languages/R/library/parallel/help/parallel.rdb = rw-r--r-- -jre/languages/R/library/tools/NAMESPACE = rw-r--r-- -jre/languages/R/library/tools/DESCRIPTION = rw-r--r-- -jre/languages/R/library/tools/INDEX = rw-r--r-- -jre/languages/R/library/tools/R/tools = rw-r--r-- -jre/languages/R/library/tools/R/tools.rdb = rw-r--r-- -jre/languages/R/library/tools/R/tools.rdx = rw-r--r-- -jre/languages/R/library/tools/R/sysdata.rdb = rw-r--r-- -jre/languages/R/library/tools/R/sysdata.rdx = rw-r--r-- -jre/languages/R/library/tools/Meta/links.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/features.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/package.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/tools/html/R.css = rw-r--r-- -jre/languages/R/library/tools/html/00Index.html = rw-r--r-- -jre/languages/R/library/tools/libs/tools.so = rwxr-xr-x -jre/languages/R/library/tools/help/AnIndex = rw-r--r-- -jre/languages/R/library/tools/help/aliases.rds = rw-r--r-- -jre/languages/R/library/tools/help/tools.rdb = rw-r--r-- -jre/languages/R/library/tools/help/tools.rdx = rw-r--r-- -jre/languages/R/library/tools/help/paths.rds = rw-r--r-- -jre/languages/R/library/methods/NAMESPACE = rw-r--r-- -jre/languages/R/library/methods/DESCRIPTION = rw-r--r-- -jre/languages/R/library/methods/INDEX = rw-r--r-- -jre/languages/R/library/methods/R/methods = rw-r--r-- -jre/languages/R/library/methods/R/methods.rdx = rw-r--r-- -jre/languages/R/library/methods/R/methods.rdb = rw-r--r-- -jre/languages/R/library/methods/Meta/links.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/features.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/package.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/methods/html/R.css = rw-r--r-- -jre/languages/R/library/methods/html/00Index.html = rw-r--r-- -jre/languages/R/library/methods/libs/methods.so = rwxr-xr-x -jre/languages/R/library/methods/help/AnIndex = rw-r--r-- -jre/languages/R/library/methods/help/aliases.rds = rw-r--r-- -jre/languages/R/library/methods/help/paths.rds = rw-r--r-- -jre/languages/R/library/methods/help/methods.rdx = rw-r--r-- -jre/languages/R/library/methods/help/methods.rdb = rw-r--r-- -jre/languages/R/library/boot/CITATION = rw-r--r-- -jre/languages/R/library/boot/NAMESPACE = rw-r--r-- -jre/languages/R/library/boot/bd.q = rw-r--r-- -jre/languages/R/library/boot/DESCRIPTION = rw-r--r-- -jre/languages/R/library/boot/INDEX = rw-r--r-- -jre/languages/R/library/boot/R/bootfuns.q = rw-r--r-- -jre/languages/R/library/boot/R/boot = rw-r--r-- -jre/languages/R/library/boot/R/bootpracs.q = rw-r--r-- -jre/languages/R/library/boot/R/boot.rdb = rw-r--r-- -jre/languages/R/library/boot/R/boot.rdx = rw-r--r-- -jre/languages/R/library/boot/Meta/data.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/links.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/features.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/package.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/boot/html/R.css = rw-r--r-- -jre/languages/R/library/boot/html/00Index.html = rw-r--r-- -jre/languages/R/library/boot/po/pl/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/ru/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/en@quot/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/de/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/ko/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/fr/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/boot/help/AnIndex = rw-r--r-- -jre/languages/R/library/boot/help/aliases.rds = rw-r--r-- -jre/languages/R/library/boot/help/paths.rds = rw-r--r-- -jre/languages/R/library/boot/help/boot.rdb = rw-r--r-- -jre/languages/R/library/boot/help/boot.rdx = rw-r--r-- -jre/languages/R/library/datasets/NAMESPACE = rw-r--r-- -jre/languages/R/library/datasets/DESCRIPTION = rw-r--r-- -jre/languages/R/library/datasets/INDEX = rw-r--r-- -jre/languages/R/library/datasets/Meta/data.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/links.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/features.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/package.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/datasets/html/R.css = rw-r--r-- -jre/languages/R/library/datasets/html/00Index.html = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/datasets/data/morley.tab = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/datasets/help/AnIndex = rw-r--r-- -jre/languages/R/library/datasets/help/aliases.rds = rw-r--r-- -jre/languages/R/library/datasets/help/paths.rds = rw-r--r-- -jre/languages/R/library/datasets/help/datasets.rdx = rw-r--r-- -jre/languages/R/library/datasets/help/datasets.rdb = rw-r--r-- -jre/languages/R/library/nnet/CITATION = rw-r--r-- -jre/languages/R/library/nnet/NAMESPACE = rw-r--r-- -jre/languages/R/library/nnet/DESCRIPTION = rw-r--r-- -jre/languages/R/library/nnet/NEWS = rw-r--r-- -jre/languages/R/library/nnet/INDEX = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.R = rw-r--r-- -jre/languages/R/library/nnet/R/nnet = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.rdx = rw-r--r-- -jre/languages/R/library/nnet/R/zzz.R = rw-r--r-- -jre/languages/R/library/nnet/R/multinom.R = rw-r--r-- -jre/languages/R/library/nnet/R/vcovmultinom.R = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.rdb = rw-r--r-- -jre/languages/R/library/nnet/Meta/links.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/features.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/package.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/nnet/html/R.css = rw-r--r-- -jre/languages/R/library/nnet/html/00Index.html = rw-r--r-- -jre/languages/R/library/nnet/libs/nnet.so = rwxr-xr-x -jre/languages/R/library/nnet/po/pl/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/en@quot/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/de/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/ko/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/fr/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/help/AnIndex = rw-r--r-- -jre/languages/R/library/nnet/help/aliases.rds = rw-r--r-- -jre/languages/R/library/nnet/help/paths.rds = rw-r--r-- -jre/languages/R/library/nnet/help/nnet.rdx = rw-r--r-- -jre/languages/R/library/nnet/help/nnet.rdb = rw-r--r-- -jre/languages/R/library/utils/iconvlist = rw-r--r-- -jre/languages/R/library/utils/NAMESPACE = rw-r--r-- -jre/languages/R/library/utils/DESCRIPTION = rw-r--r-- -jre/languages/R/library/utils/INDEX = rw-r--r-- -jre/languages/R/library/utils/misc/exDIF.dif = rw-r--r-- -jre/languages/R/library/utils/misc/exDIF.csv = rw-r--r-- -jre/languages/R/library/utils/R/utils = rw-r--r-- -jre/languages/R/library/utils/R/sysdata.rdb = rw-r--r-- -jre/languages/R/library/utils/R/sysdata.rdx = rw-r--r-- -jre/languages/R/library/utils/R/utils.rdx = rw-r--r-- -jre/languages/R/library/utils/R/utils.rdb = rw-r--r-- -jre/languages/R/library/utils/Meta/links.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/features.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/package.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/utils/html/R.css = rw-r--r-- -jre/languages/R/library/utils/html/00Index.html = rw-r--r-- -jre/languages/R/library/utils/libs/utils.so = rwxr-xr-x -jre/languages/R/library/utils/Sweave/Sweave-test-1.Rnw = rw-r--r-- -jre/languages/R/library/utils/Sweave/example-1.Rnw = rw-r--r-- -jre/languages/R/library/utils/doc/Sweave.pdf = rw-r--r-- -jre/languages/R/library/utils/help/AnIndex = rw-r--r-- -jre/languages/R/library/utils/help/aliases.rds = rw-r--r-- -jre/languages/R/library/utils/help/paths.rds = rw-r--r-- -jre/languages/R/library/utils/help/utils.rdx = rw-r--r-- -jre/languages/R/library/utils/help/utils.rdb = rw-r--r-- -jre/languages/R/library/stats4/NAMESPACE = rw-r--r-- -jre/languages/R/library/stats4/DESCRIPTION = rw-r--r-- -jre/languages/R/library/stats4/INDEX = rw-r--r-- -jre/languages/R/library/stats4/R/stats4 = rw-r--r-- -jre/languages/R/library/stats4/R/stats4.rdx = rw-r--r-- -jre/languages/R/library/stats4/R/stats4.rdb = rw-r--r-- -jre/languages/R/library/stats4/Meta/links.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/features.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/package.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/stats4/html/R.css = rw-r--r-- -jre/languages/R/library/stats4/html/00Index.html = rw-r--r-- -jre/languages/R/library/stats4/help/AnIndex = rw-r--r-- -jre/languages/R/library/stats4/help/aliases.rds = rw-r--r-- -jre/languages/R/library/stats4/help/paths.rds = rw-r--r-- -jre/languages/R/library/stats4/help/stats4.rdx = rw-r--r-- -jre/languages/R/library/stats4/help/stats4.rdb = rw-r--r-- -jre/languages/R/library/rpart/NEWS.Rd = rw-r--r-- -jre/languages/R/library/rpart/NAMESPACE = rw-r--r-- -jre/languages/R/library/rpart/DESCRIPTION = rw-r--r-- -jre/languages/R/library/rpart/INDEX = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.exp.R = rw-r--r-- -jre/languages/R/library/rpart/R/predict.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.class.R = rw-r--r-- -jre/languages/R/library/rpart/R/post.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpartco.R = rw-r--r-- -jre/languages/R/library/rpart/R/plotcp.R = rw-r--r-- -jre/languages/R/library/rpart/R/path.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/prune.R = rw-r--r-- -jre/languages/R/library/rpart/R/labels.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/pred.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/xpred.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/na.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/snip.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.anova.R = rw-r--r-- -jre/languages/R/library/rpart/R/text.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.control.R = rw-r--r-- -jre/languages/R/library/rpart/R/printcp.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.poisson.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart = rw-r--r-- -jre/languages/R/library/rpart/R/rsq.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/formatg.R = rw-r--r-- -jre/languages/R/library/rpart/R/prune.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.branch.R = rw-r--r-- -jre/languages/R/library/rpart/R/roc.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/snip.rpart.mouse.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.rdx = rw-r--r-- -jre/languages/R/library/rpart/R/meanvar.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.rdb = rw-r--r-- -jre/languages/R/library/rpart/R/post.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/zzz.R = rw-r--r-- -jre/languages/R/library/rpart/R/summary.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpartcallback.R = rw-r--r-- -jre/languages/R/library/rpart/R/importance.R = rw-r--r-- -jre/languages/R/library/rpart/R/residuals.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.matrix.R = rw-r--r-- -jre/languages/R/library/rpart/R/model.frame.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/print.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/plot.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/data.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/links.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/features.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/package.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/rpart/html/R.css = rw-r--r-- -jre/languages/R/library/rpart/html/00Index.html = rw-r--r-- -jre/languages/R/library/rpart/libs/rpart.so = rwxr-xr-x -jre/languages/R/library/rpart/po/pl/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/pl/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ru/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ru/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/en@quot/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/en@quot/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/de/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/de/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ko/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ko/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/fr/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/fr/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/doc/index.html = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.R = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.Rnw = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.pdf = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.Rnw = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.pdf = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.R = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/rpart/help/AnIndex = rw-r--r-- -jre/languages/R/library/rpart/help/aliases.rds = rw-r--r-- -jre/languages/R/library/rpart/help/paths.rds = rw-r--r-- -jre/languages/R/library/rpart/help/rpart.rdx = rw-r--r-- -jre/languages/R/library/rpart/help/rpart.rdb = rw-r--r-- -jre/languages/R/library/lattice/CITATION = rw-r--r-- -jre/languages/R/library/lattice/NAMESPACE = rw-r--r-- -jre/languages/R/library/lattice/DESCRIPTION = rw-r--r-- -jre/languages/R/library/lattice/NEWS = rw-r--r-- -jre/languages/R/library/lattice/INDEX = rw-r--r-- -jre/languages/R/library/lattice/demo/intervals.R = rw-r--r-- -jre/languages/R/library/lattice/demo/panel.R = rw-r--r-- -jre/languages/R/library/lattice/demo/lattice.R = rw-r--r-- -jre/languages/R/library/lattice/demo/labels.R = rw-r--r-- -jre/languages/R/library/lattice/R/qq.R = rw-r--r-- -jre/languages/R/library/lattice/R/axis.R = rw-r--r-- -jre/languages/R/library/lattice/R/shingle.R = rw-r--r-- -jre/languages/R/library/lattice/R/settings.R = rw-r--r-- -jre/languages/R/library/lattice/R/summary.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/qqmath.R = rw-r--r-- -jre/languages/R/library/lattice/R/legend.R = rw-r--r-- -jre/languages/R/library/lattice/R/densityplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/panel.smoothscatter.R = rw-r--r-- -jre/languages/R/library/lattice/R/rfs.R = rw-r--r-- -jre/languages/R/library/lattice/R/interaction.R = rw-r--r-- -jre/languages/R/library/lattice/R/xyplot.ts.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice.rdb = rw-r--r-- -jre/languages/R/library/lattice/R/update.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/bwplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/cloud.R = rw-r--r-- -jre/languages/R/library/lattice/R/panel.superpose.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice.rdx = rw-r--r-- -jre/languages/R/library/lattice/R/panel.smooth.R = rw-r--r-- -jre/languages/R/library/lattice/R/levelplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice = rw-r--r-- -jre/languages/R/library/lattice/R/common.R = rw-r--r-- -jre/languages/R/library/lattice/R/panels.R = rw-r--r-- -jre/languages/R/library/lattice/R/layout.R = rw-r--r-- -jre/languages/R/library/lattice/R/miscellaneous.R = rw-r--r-- -jre/languages/R/library/lattice/R/make.groups.R = rw-r--r-- -jre/languages/R/library/lattice/R/histogram.R = rw-r--r-- -jre/languages/R/library/lattice/R/strip.R = rw-r--r-- -jre/languages/R/library/lattice/R/xyplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/scales.R = rw-r--r-- -jre/languages/R/library/lattice/R/zzz.R = rw-r--r-- -jre/languages/R/library/lattice/R/splom.R = rw-r--r-- -jre/languages/R/library/lattice/R/print.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/tmd.R = rw-r--r-- -jre/languages/R/library/lattice/R/parallel.R = rw-r--r-- -jre/languages/R/library/lattice/Meta/data.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/links.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/features.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/package.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/lattice/html/R.css = rw-r--r-- -jre/languages/R/library/lattice/html/00Index.html = rw-r--r-- -jre/languages/R/library/lattice/libs/lattice.so = rwxr-xr-x -jre/languages/R/library/lattice/po/pl/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/en@quot/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/de/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/ko/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/fr/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/lattice/help/AnIndex = rw-r--r-- -jre/languages/R/library/lattice/help/aliases.rds = rw-r--r-- -jre/languages/R/library/lattice/help/lattice.rdb = rw-r--r-- -jre/languages/R/library/lattice/help/lattice.rdx = rw-r--r-- -jre/languages/R/library/lattice/help/paths.rds = rw-r--r-- -jre/languages/R/library/nlme/CITATION = rw-r--r-- -jre/languages/R/library/nlme/NAMESPACE = rw-r--r-- -jre/languages/R/library/nlme/DESCRIPTION = rw-r--r-- -jre/languages/R/library/nlme/INDEX = rw-r--r-- -jre/languages/R/library/nlme/LICENCE = rw-r--r-- -jre/languages/R/library/nlme/mlbook/ch04.R = rw-r--r-- -jre/languages/R/library/nlme/mlbook/README = rw-r--r-- -jre/languages/R/library/nlme/mlbook/ch05.R = rw-r--r-- -jre/languages/R/library/nlme/R/gls.R = rw-r--r-- -jre/languages/R/library/nlme/R/simulate.R = rw-r--r-- -jre/languages/R/library/nlme/R/pdMat.R = rw-r--r-- -jre/languages/R/library/nlme/R/corStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/newFunc.R = rw-r--r-- -jre/languages/R/library/nlme/R/gnls.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.rdb = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.rdx = rw-r--r-- -jre/languages/R/library/nlme/R/VarCov.R = rw-r--r-- -jre/languages/R/library/nlme/R/lmList.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme = rw-r--r-- -jre/languages/R/library/nlme/R/reStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/newMethods.R = rw-r--r-- -jre/languages/R/library/nlme/R/zzMethods.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlsList.R = rw-r--r-- -jre/languages/R/library/nlme/R/VarCorr.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.R = rw-r--r-- -jre/languages/R/library/nlme/R/newGenerics.R = rw-r--r-- -jre/languages/R/library/nlme/R/lme.R = rw-r--r-- -jre/languages/R/library/nlme/R/varFunc.R = rw-r--r-- -jre/languages/R/library/nlme/R/modelStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/groupedData.R = rw-r--r-- -jre/languages/R/library/nlme/Meta/data.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/links.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/features.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/package.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/nlme/html/R.css = rw-r--r-- -jre/languages/R/library/nlme/html/00Index.html = rw-r--r-- -jre/languages/R/library/nlme/libs/nlme.so = rwxr-xr-x -jre/languages/R/library/nlme/po/pl/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/pl/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/en@quot/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/en@quot/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/de/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/de/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/ko/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/ko/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/fr/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/fr/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch03.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch04.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/runme.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/sims.rda = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch05.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch01.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch06.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch02.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch08.R = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/nlme/help/AnIndex = rw-r--r-- -jre/languages/R/library/nlme/help/aliases.rds = rw-r--r-- -jre/languages/R/library/nlme/help/nlme.rdb = rw-r--r-- -jre/languages/R/library/nlme/help/nlme.rdx = rw-r--r-- -jre/languages/R/library/nlme/help/paths.rds = rw-r--r-- -jre/languages/R/library/splines/NAMESPACE = rw-r--r-- -jre/languages/R/library/splines/DESCRIPTION = rw-r--r-- -jre/languages/R/library/splines/INDEX = rw-r--r-- -jre/languages/R/library/splines/R/splines = rw-r--r-- -jre/languages/R/library/splines/R/splines.rdb = rw-r--r-- -jre/languages/R/library/splines/R/splines.rdx = rw-r--r-- -jre/languages/R/library/splines/Meta/links.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/features.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/package.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/splines/html/R.css = rw-r--r-- -jre/languages/R/library/splines/html/00Index.html = rw-r--r-- -jre/languages/R/library/splines/libs/splines.so = rwxr-xr-x -jre/languages/R/library/splines/help/AnIndex = rw-r--r-- -jre/languages/R/library/splines/help/aliases.rds = rw-r--r-- -jre/languages/R/library/splines/help/paths.rds = rw-r--r-- -jre/languages/R/library/splines/help/splines.rdb = rw-r--r-- -jre/languages/R/library/splines/help/splines.rdx = rw-r--r-- -jre/languages/R/library/grDevices/NAMESPACE = rw-r--r-- -jre/languages/R/library/grDevices/DESCRIPTION = rw-r--r-- -jre/languages/R/library/grDevices/INDEX = rw-r--r-- -jre/languages/R/library/grDevices/demo/hclColors.R = rw-r--r-- -jre/languages/R/library/grDevices/demo/colors.R = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices.rdb = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices.rdx = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices = rw-r--r-- -jre/languages/R/library/grDevices/Meta/links.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/features.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/package.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/grDevices/html/R.css = rw-r--r-- -jre/languages/R/library/grDevices/html/00Index.html = rw-r--r-- -jre/languages/R/library/grDevices/icc/srgb = rw-r--r-- -jre/languages/R/library/grDevices/icc/srgb.flate = rw-r--r-- -jre/languages/R/library/grDevices/afm/cob_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvbo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvnbo___.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019064l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agd_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncb_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-Oblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/s050000l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkdi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/poi_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvno____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agw_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019043l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Roman.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvnb____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/sy______.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059013l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvo_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tii_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-Oblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncr_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010015l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Italic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/MustRead.html = rw-r--r-- -jre/languages/R/library/grDevices/afm/Symbol.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010033l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/com_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018015l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncbi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkd_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-BoldItalic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018032l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_regular_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059036l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/README = rw-r--r-- -jre/languages/R/library/grDevices/afm/cmti10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059033l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-Italic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agwo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvn_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-BoldOblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019063l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tibi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/coo_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/por_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agdo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_symbol_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ZapfDingbats.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/cobo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvb_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-BoldItalic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkli____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019044l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/pobi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tir_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018012l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkl_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/nci_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_boldx_italic_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hv______.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_italic_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059016l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/pob_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-BoldOblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010013l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/cmbxti10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tib_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018035l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_boldx_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010035l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/libs/grDevices.so = rwxr-xr-x -jre/languages/R/library/grDevices/enc/AdobeSym.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin7.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin2.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin1.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/Greek.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1257.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1250.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/TeXtext.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/PDFDoc.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1251.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1253.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/KOI8-U.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/Cyrillic.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/MacRoman.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/AdobeStd.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/KOI8-R.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin9.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/WinAnsi.enc = rw-r--r-- -jre/languages/R/library/grDevices/help/AnIndex = rw-r--r-- -jre/languages/R/library/grDevices/help/grDevices.rdb = rw-r--r-- -jre/languages/R/library/grDevices/help/grDevices.rdx = rw-r--r-- -jre/languages/R/library/grDevices/help/aliases.rds = rw-r--r-- -jre/languages/R/library/grDevices/help/paths.rds = rw-r--r-- -jre/languages/R/library/class/CITATION = rw-r--r-- -jre/languages/R/library/class/NAMESPACE = rw-r--r-- -jre/languages/R/library/class/DESCRIPTION = rw-r--r-- -jre/languages/R/library/class/NEWS = rw-r--r-- -jre/languages/R/library/class/INDEX = rw-r--r-- -jre/languages/R/library/class/R/class.rdb = rw-r--r-- -jre/languages/R/library/class/R/class.rdx = rw-r--r-- -jre/languages/R/library/class/R/multiedit.R = rw-r--r-- -jre/languages/R/library/class/R/SOM.R = rw-r--r-- -jre/languages/R/library/class/R/lvq.R = rw-r--r-- -jre/languages/R/library/class/R/class = rw-r--r-- -jre/languages/R/library/class/R/zzz.R = rw-r--r-- -jre/languages/R/library/class/R/knn.R = rw-r--r-- -jre/languages/R/library/class/Meta/links.rds = rw-r--r-- -jre/languages/R/library/class/Meta/features.rds = rw-r--r-- -jre/languages/R/library/class/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/class/Meta/package.rds = rw-r--r-- -jre/languages/R/library/class/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/class/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/class/html/R.css = rw-r--r-- -jre/languages/R/library/class/html/00Index.html = rw-r--r-- -jre/languages/R/library/class/libs/class.so = rwxr-xr-x -jre/languages/R/library/class/po/pl/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/en@quot/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/de/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/ko/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/fr/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/help/class.rdb = rw-r--r-- -jre/languages/R/library/class/help/class.rdx = rw-r--r-- -jre/languages/R/library/class/help/AnIndex = rw-r--r-- -jre/languages/R/library/class/help/aliases.rds = rw-r--r-- -jre/languages/R/library/class/help/paths.rds = rw-r--r-- -jre/languages/R/library/codetools/NAMESPACE = rw-r--r-- -jre/languages/R/library/codetools/DESCRIPTION = rw-r--r-- -jre/languages/R/library/codetools/INDEX = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.rdx = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.R = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.rdb = rw-r--r-- -jre/languages/R/library/codetools/R/codetools = rw-r--r-- -jre/languages/R/library/codetools/Meta/links.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/features.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/package.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/codetools/html/R.css = rw-r--r-- -jre/languages/R/library/codetools/html/00Index.html = rw-r--r-- -jre/languages/R/library/codetools/help/AnIndex = rw-r--r-- -jre/languages/R/library/codetools/help/codetools.rdx = rw-r--r-- -jre/languages/R/library/codetools/help/codetools.rdb = rw-r--r-- -jre/languages/R/library/codetools/help/aliases.rds = rw-r--r-- -jre/languages/R/library/codetools/help/paths.rds = rw-r--r-- -jre/languages/R/library/spatial/CITATION = rw-r--r-- -jre/languages/R/library/spatial/PP.files = rw-r--r-- -jre/languages/R/library/spatial/NAMESPACE = rw-r--r-- -jre/languages/R/library/spatial/DESCRIPTION = rw-r--r-- -jre/languages/R/library/spatial/NEWS = rw-r--r-- -jre/languages/R/library/spatial/INDEX = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig1c.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/davis.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig1b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/cells.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pines.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/caveolae.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pereg.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/hccells.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/agter.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/eagles.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/tokyo.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/grocery.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/drumlin.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pairfn.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/nztrees.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig2a.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/redwood.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig2b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/towns.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/stowns1.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3c.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/schools.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3a.dat = rw-r--r-- -jre/languages/R/library/spatial/R/kr.R = rw-r--r-- -jre/languages/R/library/spatial/R/zzz.R = rw-r--r-- -jre/languages/R/library/spatial/R/spatial = rw-r--r-- -jre/languages/R/library/spatial/R/spatial.rdb = rw-r--r-- -jre/languages/R/library/spatial/R/spatial.rdx = rw-r--r-- -jre/languages/R/library/spatial/R/pp.R = rw-r--r-- -jre/languages/R/library/spatial/Meta/links.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/features.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/package.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/spatial/html/R.css = rw-r--r-- -jre/languages/R/library/spatial/html/00Index.html = rw-r--r-- -jre/languages/R/library/spatial/libs/spatial.so = rwxr-xr-x -jre/languages/R/library/spatial/po/pl/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/en@quot/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/de/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/ko/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/fr/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/help/AnIndex = rw-r--r-- -jre/languages/R/library/spatial/help/aliases.rds = rw-r--r-- -jre/languages/R/library/spatial/help/paths.rds = rw-r--r-- -jre/languages/R/library/spatial/help/spatial.rdb = rw-r--r-- -jre/languages/R/library/spatial/help/spatial.rdx = rw-r--r-- -jre/languages/R/library/graphics/NAMESPACE = rw-r--r-- -jre/languages/R/library/graphics/DESCRIPTION = rw-r--r-- -jre/languages/R/library/graphics/INDEX = rw-r--r-- -jre/languages/R/library/graphics/demo/Japanese.R = rw-r--r-- -jre/languages/R/library/graphics/demo/plotmath.R = rw-r--r-- -jre/languages/R/library/graphics/demo/persp.R = rw-r--r-- -jre/languages/R/library/graphics/demo/graphics.R = rw-r--r-- -jre/languages/R/library/graphics/demo/image.R = rw-r--r-- -jre/languages/R/library/graphics/demo/Hershey.R = rw-r--r-- -jre/languages/R/library/graphics/R/graphics.rdb = rw-r--r-- -jre/languages/R/library/graphics/R/graphics.rdx = rw-r--r-- -jre/languages/R/library/graphics/R/graphics = rw-r--r-- -jre/languages/R/library/graphics/Meta/links.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/features.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/package.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/graphics/html/R.css = rw-r--r-- -jre/languages/R/library/graphics/html/00Index.html = rw-r--r-- -jre/languages/R/library/graphics/libs/graphics.so = rwxr-xr-x -jre/languages/R/library/graphics/help/AnIndex = rw-r--r-- -jre/languages/R/library/graphics/help/aliases.rds = rw-r--r-- -jre/languages/R/library/graphics/help/graphics.rdb = rw-r--r-- -jre/languages/R/library/graphics/help/graphics.rdx = rw-r--r-- -jre/languages/R/library/graphics/help/paths.rds = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.svg = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.pdf = rw-r--r-- -jre/languages/R/library/graphics/help/figures/oma.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/oma.pdf = rw-r--r-- -jre/languages/R/library/graphics/help/figures/mai.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/mai.pdf = rw-r--r-- -jre/languages/R/library/foreign/COPYRIGHTS = rw-r--r-- -jre/languages/R/library/foreign/NAMESPACE = rw-r--r-- -jre/languages/R/library/foreign/DESCRIPTION = rw-r--r-- -jre/languages/R/library/foreign/INDEX = rw-r--r-- -jre/languages/R/library/foreign/R/read.dta.R = rw-r--r-- -jre/languages/R/library/foreign/R/read.ssd.R = rw-r--r-- -jre/languages/R/library/foreign/R/minitab.R = rw-r--r-- -jre/languages/R/library/foreign/R/dbf.R = rw-r--r-- -jre/languages/R/library/foreign/R/octave.R = rw-r--r-- -jre/languages/R/library/foreign/R/spss.R = rw-r--r-- -jre/languages/R/library/foreign/R/R_systat.R = rw-r--r-- -jre/languages/R/library/foreign/R/xport.R = rw-r--r-- -jre/languages/R/library/foreign/R/zzz.R = rw-r--r-- -jre/languages/R/library/foreign/R/read.epiinfo.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign.rdb = rw-r--r-- -jre/languages/R/library/foreign/R/Sread.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign.rdx = rw-r--r-- -jre/languages/R/library/foreign/R/arff.R = rw-r--r-- -jre/languages/R/library/foreign/R/writeForeignSAS.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign = rw-r--r-- -jre/languages/R/library/foreign/R/writeForeignCode.R = rw-r--r-- -jre/languages/R/library/foreign/Meta/links.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/features.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/package.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/foreign/html/R.css = rw-r--r-- -jre/languages/R/library/foreign/html/00Index.html = rw-r--r-- -jre/languages/R/library/foreign/libs/foreign.so = rwxr-xr-x -jre/languages/R/library/foreign/po/pl/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/pl/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/en@quot/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/en@quot/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/de/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/de/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/fr/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/fr/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/files/electric.sav = rw-r--r-- -jre/languages/R/library/foreign/files/Iris.syd = rw-r--r-- -jre/languages/R/library/foreign/files/testdata.sav = rw-r--r-- -jre/languages/R/library/foreign/files/HillRace.SYD = rw-r--r-- -jre/languages/R/library/foreign/files/sids.dbf = rwxr-xr-x -jre/languages/R/library/foreign/help/AnIndex = rw-r--r-- -jre/languages/R/library/foreign/help/aliases.rds = rw-r--r-- -jre/languages/R/library/foreign/help/paths.rds = rw-r--r-- -jre/languages/R/library/foreign/help/foreign.rdb = rw-r--r-- -jre/languages/R/library/foreign/help/foreign.rdx = rw-r--r-- -jre/languages/R/library/compiler/NAMESPACE = rw-r--r-- -jre/languages/R/library/compiler/DESCRIPTION = rw-r--r-- -jre/languages/R/library/compiler/INDEX = rw-r--r-- -jre/languages/R/library/compiler/R/compiler = rw-r--r-- -jre/languages/R/library/compiler/R/compiler.rdx = rw-r--r-- -jre/languages/R/library/compiler/R/compiler.rdb = rw-r--r-- -jre/languages/R/library/compiler/Meta/links.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/features.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/package.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/compiler/html/R.css = rw-r--r-- -jre/languages/R/library/compiler/html/00Index.html = rw-r--r-- -jre/languages/R/library/compiler/help/AnIndex = rw-r--r-- -jre/languages/R/library/compiler/help/aliases.rds = rw-r--r-- -jre/languages/R/library/compiler/help/paths.rds = rw-r--r-- -jre/languages/R/library/compiler/help/compiler.rdx = rw-r--r-- -jre/languages/R/library/compiler/help/compiler.rdb = rw-r--r-- -jre/languages/R/library/Matrix/Copyrights = rw-r--r-- -jre/languages/R/library/Matrix/NEWS.Rd = rw-r--r-- -jre/languages/R/library/Matrix/test-tools-1.R = rw-r--r-- -jre/languages/R/library/Matrix/NAMESPACE = rw-r--r-- -jre/languages/R/library/Matrix/DESCRIPTION = rw-r--r-- -jre/languages/R/library/Matrix/INDEX = rw-r--r-- -jre/languages/R/library/Matrix/test-tools-Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/Doxyfile = rw-r--r-- -jre/languages/R/library/Matrix/test-tools.R = rw-r--r-- -jre/languages/R/library/Matrix/LICENCE = rw-r--r-- -jre/languages/R/library/Matrix/include/Matrix.h = rw-r--r-- -jre/languages/R/library/Matrix/include/Matrix_stubs.c = rw-r--r-- -jre/languages/R/library/Matrix/include/cholmod.h = rw-r--r-- -jre/languages/R/library/Matrix/R/expm.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Auxiliaries.R = rw-r--r-- -jre/languages/R/library/Matrix/R/corMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ngTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/rankMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ndenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/SparseM-conv.R = rw-r--r-- -jre/languages/R/library/Matrix/R/indMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseQR.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Tsparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ntCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/spModels.R = rw-r--r-- -jre/languages/R/library/Matrix/R/LU.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dppMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/AllClass.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Csparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/pMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ntTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/MatrixFactorization.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ddenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/AllGeneric.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/kronecker.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.rdb = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.rdx = rw-r--r-- -jre/languages/R/library/Matrix/R/not.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ngCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dpoMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/denseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/triangularMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/KhatriRao.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtrMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dspMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/bind2.R = rw-r--r-- -jre/languages/R/library/Matrix/R/abIndex.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsyMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/condest.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Rsparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lgTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/eigen.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Math.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseVector.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgeMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nnzero.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ltCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/zzz.R = rw-r--r-- -jre/languages/R/library/Matrix/R/CHMfactor.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Hilbert.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ltTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Ops.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/diagMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix = rw-r--r-- -jre/languages/R/library/Matrix/R/nearPD.R = rw-r--r-- -jre/languages/R/library/Matrix/R/products.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtpMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/colSums.R = rw-r--r-- -jre/languages/R/library/Matrix/R/HBMM.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Summary.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ldenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/bandSparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lgCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/symmetricMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/data.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/links.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/features.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/package.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/Matrix/html/R.css = rw-r--r-- -jre/languages/R/library/Matrix/html/00Index.html = rw-r--r-- -jre/languages/R/library/Matrix/libs/Matrix.so = rwxr-xr-x -jre/languages/R/library/Matrix/po/pl/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/pl/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/en@quot/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/en@quot/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/de/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/de/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/ko/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/fr/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/fr/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/doc/index.html = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Announce.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/SPQR.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/CHOLMOD.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/SuiteSparse_config.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/UserGuides.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/AMD.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/COLAMD.txt = rw-r--r-- -jre/languages/R/library/Matrix/external/lund_a.rsa = rw-r--r-- -jre/languages/R/library/Matrix/external/CAex_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/test3comp.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/utm300.rua = rw-r--r-- -jre/languages/R/library/Matrix/external/USCounties_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/lund_a.mtx = rw-r--r-- -jre/languages/R/library/Matrix/external/wrong.mtx = rw-r--r-- -jre/languages/R/library/Matrix/external/symA.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/KNex_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/symW.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/pores_1.mtx = rw-r--r-- -jre/languages/R/library/Matrix/data/KNex.R = rw-r--r-- -jre/languages/R/library/Matrix/data/CAex.R = rw-r--r-- -jre/languages/R/library/Matrix/data/USCounties.R = rw-r--r-- -jre/languages/R/library/Matrix/help/AnIndex = rw-r--r-- -jre/languages/R/library/Matrix/help/aliases.rds = rw-r--r-- -jre/languages/R/library/Matrix/help/Matrix.rdb = rw-r--r-- -jre/languages/R/library/Matrix/help/Matrix.rdx = rw-r--r-- -jre/languages/R/library/Matrix/help/paths.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/NAMESPACE = rw-r--r-- -jre/languages/R/library/KernSmooth/DESCRIPTION = rw-r--r-- -jre/languages/R/library/KernSmooth/INDEX = rw-r--r-- -jre/languages/R/library/KernSmooth/R/all.R = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth.rdb = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth.rdx = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/links.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/features.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/package.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/html/R.css = rw-r--r-- -jre/languages/R/library/KernSmooth/html/00Index.html = rw-r--r-- -jre/languages/R/library/KernSmooth/libs/KernSmooth.so = rwxr-xr-x -jre/languages/R/library/KernSmooth/po/pl/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/en@quot/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/de/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/ko/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/fr/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/help/AnIndex = rw-r--r-- -jre/languages/R/library/KernSmooth/help/aliases.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/help/paths.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/help/KernSmooth.rdb = rw-r--r-- -jre/languages/R/library/KernSmooth/help/KernSmooth.rdx = rw-r--r-- -jre/languages/R/library/base/CITATION = rw-r--r-- -jre/languages/R/library/base/DESCRIPTION = rw-r--r-- -jre/languages/R/library/base/INDEX = rw-r--r-- -jre/languages/R/library/base/demo/scoping.R = rw-r--r-- -jre/languages/R/library/base/demo/error.catching.R = rw-r--r-- -jre/languages/R/library/base/demo/is.things.R = rw-r--r-- -jre/languages/R/library/base/demo/recursion.R = rw-r--r-- -jre/languages/R/library/base/R/Rprofile = rw-r--r-- -jre/languages/R/library/base/R/base.rdx = rw-r--r-- -jre/languages/R/library/base/R/base.rdb = rw-r--r-- -jre/languages/R/library/base/R/base = rw-r--r-- -jre/languages/R/library/base/Meta/links.rds = rw-r--r-- -jre/languages/R/library/base/Meta/features.rds = rw-r--r-- -jre/languages/R/library/base/Meta/package.rds = rw-r--r-- -jre/languages/R/library/base/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/base/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/base/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/base/html/R.css = rw-r--r-- -jre/languages/R/library/base/html/00Index.html = rw-r--r-- -jre/languages/R/library/base/libs/base.so = rwxr-xr-x -jre/languages/R/library/base/help/AnIndex = rw-r--r-- -jre/languages/R/library/base/help/aliases.rds = rw-r--r-- -jre/languages/R/library/base/help/paths.rds = rw-r--r-- -jre/languages/R/library/base/help/base.rdx = rw-r--r-- -jre/languages/R/library/base/help/base.rdb = rw-r--r-- -jre/languages/R/library/stats/COPYRIGHTS.modreg = rw-r--r-- -jre/languages/R/library/stats/NAMESPACE = rw-r--r-- -jre/languages/R/library/stats/SOURCES.ts = rw-r--r-- -jre/languages/R/library/stats/DESCRIPTION = rw-r--r-- -jre/languages/R/library/stats/INDEX = rw-r--r-- -jre/languages/R/library/stats/demo/smooth.R = rw-r--r-- -jre/languages/R/library/stats/demo/lm.glm.R = rw-r--r-- -jre/languages/R/library/stats/demo/nlm.R = rw-r--r-- -jre/languages/R/library/stats/demo/glm.vr.R = rw-r--r-- -jre/languages/R/library/stats/R/stats.rdx = rw-r--r-- -jre/languages/R/library/stats/R/stats.rdb = rw-r--r-- -jre/languages/R/library/stats/R/stats = rw-r--r-- -jre/languages/R/library/stats/Meta/links.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/features.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/package.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/stats/html/R.css = rw-r--r-- -jre/languages/R/library/stats/html/00Index.html = rw-r--r-- -jre/languages/R/library/stats/libs/stats.so = rwxr-xr-x -jre/languages/R/library/stats/help/AnIndex = rw-r--r-- -jre/languages/R/library/stats/help/aliases.rds = rw-r--r-- -jre/languages/R/library/stats/help/stats.rdx = rw-r--r-- -jre/languages/R/library/stats/help/paths.rds = rw-r--r-- -jre/languages/R/library/stats/help/stats.rdb = rw-r--r-- -jre/languages/R/library/survival/CITATION = rw-r--r-- -jre/languages/R/library/survival/COPYRIGHTS = rw-r--r-- -jre/languages/R/library/survival/NEWS.Rd = rw-r--r-- -jre/languages/R/library/survival/NAMESPACE = rw-r--r-- -jre/languages/R/library/survival/DESCRIPTION = rw-r--r-- -jre/languages/R/library/survival/INDEX = rw-r--r-- -jre/languages/R/library/survival/R/print.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/plot.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cluster.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gamma.S = rw-r--r-- -jre/languages/R/library/survival/R/aareg.taper.R = rw-r--r-- -jre/languages/R/library/survival/R/survival.rdb = rw-r--r-- -jre/languages/R/library/survival/R/pspline.R = rw-r--r-- -jre/languages/R/library/survival/R/plot.survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/print.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/survival.rdx = rw-r--r-- -jre/languages/R/library/survival/R/coxph.getdata.S = rw-r--r-- -jre/languages/R/library/survival/R/coxph.rvar.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlgam.S = rw-r--r-- -jre/languages/R/library/survival/R/survfit.matrix.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survfit.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.cfit.R = rw-r--r-- -jre/languages/R/library/survival/R/survobrien.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/tmerge.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxph.penal.R = rw-r--r-- -jre/languages/R/library/survival/R/plot.cox.zph.S = rw-r--r-- -jre/languages/R/library/survival/R/basehaz.R = rw-r--r-- -jre/languages/R/library/survival/R/format.Surv.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/normalizetime.R = rw-r--r-- -jre/languages/R/library/survival/R/survfit.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/residuals.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gammacon.S = rw-r--r-- -jre/languages/R/library/survival/R/is.na.coxph.penalty.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cch.R = rw-r--r-- -jre/languages/R/library/survival/R/lines.survfit.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/anova.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/is.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/statefig.R = rw-r--r-- -jre/languages/R/library/survival/R/survreg.control.S = rw-r--r-- -jre/languages/R/library/survival/R/survreg.distributions.S = rw-r--r-- -jre/languages/R/library/survival/R/ridge.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.null.S = rw-r--r-- -jre/languages/R/library/survival/R/pyears.R = rw-r--r-- -jre/languages/R/library/survival/R/summary.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/coxph.detail.S = rw-r--r-- -jre/languages/R/library/survival/R/print.pyears.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.wtest.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/survConcordance.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitTurnbull.S = rw-r--r-- -jre/languages/R/library/survival/R/survpenal.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/survfitCI.R = rw-r--r-- -jre/languages/R/library/survival/R/attrassign.R = rw-r--r-- -jre/languages/R/library/survival/R/ratetableold.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survfitms.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.brent.S = rw-r--r-- -jre/languages/R/library/survival/R/match.ratetable.R = rwxr-xr-x -jre/languages/R/library/survival/R/firstlib.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitcoxph.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/cipoisson.R = rw-r--r-- -jre/languages/R/library/survival/R/predict.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/lines.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlgauss.S = rw-r--r-- -jre/languages/R/library/survival/R/print.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.S = rw-r--r-- -jre/languages/R/library/survival/R/strata.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/predict.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/yates.R = rw-r--r-- -jre/languages/R/library/survival/R/neardate.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survdiff.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/coxpenal.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/agexact.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/model.matrix.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/model.frame.survreg.R = rw-r--r-- -jre/languages/R/library/survival/R/lines.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cox.zph.S = rw-r--r-- -jre/languages/R/library/survival/R/survfitms.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gaussian.S = rw-r--r-- -jre/languages/R/library/survival/R/ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlaic.S = rw-r--r-- -jre/languages/R/library/survival/R/tcut.S = rw-r--r-- -jre/languages/R/library/survival/R/dsurvreg.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/clogit.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survexp.S = rw-r--r-- -jre/languages/R/library/survival/R/Surv.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitKM.S = rw-r--r-- -jre/languages/R/library/survival/R/survreg.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.t.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survfit.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/survdiff.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/aeqSurv.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxphlist.S = rw-r--r-- -jre/languages/R/library/survival/R/finegray.R = rw-r--r-- -jre/languages/R/library/survival/R/summary.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/coxpenal.df.S = rw-r--r-- -jre/languages/R/library/survival/R/ratetableDate.R = rw-r--r-- -jre/languages/R/library/survival/R/predict.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/agreg.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.survreglist.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.null.S = rw-r--r-- -jre/languages/R/library/survival/R/quantile.survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/coxexact.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/untangle.specials.S = rw-r--r-- -jre/languages/R/library/survival/R/predict.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/survConcordance.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/agsurv.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controldf.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.survreg.R = rw-r--r-- -jre/languages/R/library/survival/R/survcallback.S = rw-r--r-- -jre/languages/R/library/survival/R/logLik.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/survSplit.R = rw-r--r-- -jre/languages/R/library/survival/R/labels.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/survival = rw-r--r-- -jre/languages/R/library/survival/R/survregDtest.S = rw-r--r-- -jre/languages/R/library/survival/R/xtras.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.control.S = rw-r--r-- -jre/languages/R/library/survival/R/survdiff.fit.S = rw-r--r-- -jre/languages/R/library/survival/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/data.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/links.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/features.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/package.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/survival/html/R.css = rw-r--r-- -jre/languages/R/library/survival/html/00Index.html = rw-r--r-- -jre/languages/R/library/survival/libs/survival.so = rwxr-xr-x -jre/languages/R/library/survival/doc/adjcurve.R = rw-r--r-- -jre/languages/R/library/survival/doc/adjcurve.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/adjcurve.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/index.html = rw-r--r-- -jre/languages/R/library/survival/doc/tests.R = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/multi.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/multi.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/population.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/population.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.R = rw-r--r-- -jre/languages/R/library/survival/doc/population.R = rw-r--r-- -jre/languages/R/library/survival/doc/tests.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/tests.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/compete.R = rw-r--r-- -jre/languages/R/library/survival/doc/compete.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/compete.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.R = rw-r--r-- -jre/languages/R/library/survival/doc/validate.R = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.R = rw-r--r-- -jre/languages/R/library/survival/doc/validate.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/validate.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/multi.R = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/survival/help/survival.rdb = rw-r--r-- -jre/languages/R/library/survival/help/survival.rdx = rw-r--r-- -jre/languages/R/library/survival/help/AnIndex = rw-r--r-- -jre/languages/R/library/survival/help/aliases.rds = rw-r--r-- -jre/languages/R/library/survival/help/paths.rds = rw-r--r-- -jre/languages/R/library/grid/NAMESPACE = rw-r--r-- -jre/languages/R/library/grid/DESCRIPTION = rw-r--r-- -jre/languages/R/library/grid/INDEX = rw-r--r-- -jre/languages/R/library/grid/R/grid.rdb = rw-r--r-- -jre/languages/R/library/grid/R/grid.rdx = rw-r--r-- -jre/languages/R/library/grid/R/grid = rw-r--r-- -jre/languages/R/library/grid/Meta/links.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/features.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/package.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/grid/html/R.css = rw-r--r-- -jre/languages/R/library/grid/html/00Index.html = rw-r--r-- -jre/languages/R/library/grid/libs/grid.so = rwxr-xr-x -jre/languages/R/library/grid/doc/moveline.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/plotexample.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/saveload.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/displaylist.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/viewports.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/interactive.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/grid.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/DivByZero.txt = rw-r--r-- -jre/languages/R/library/grid/doc/rotated.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/changes.txt = rw-r--r-- -jre/languages/R/library/grid/doc/locndimn.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/frame.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/nonfinite.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/sharing.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/grobs.pdf = rw-r--r-- -jre/languages/R/library/grid/help/AnIndex = rw-r--r-- -jre/languages/R/library/grid/help/aliases.rds = rw-r--r-- -jre/languages/R/library/grid/help/grid.rdb = rw-r--r-- -jre/languages/R/library/grid/help/grid.rdx = rw-r--r-- -jre/languages/R/library/grid/help/paths.rds = rw-r--r-- -jre/languages/R/etc/edMakeconf.etc.llvm = rw-r--r-- -jre/languages/R/etc/native-packages = rw-r--r-- -jre/languages/R/etc/configure.ac = rw-r--r-- -jre/languages/R/etc/Makeconf.in = rw-r--r-- -jre/languages/R/etc/ldpaths = rw-r--r-- -jre/languages/R/etc/DEFAULT_CRAN_MIRROR = rw-r--r-- -jre/languages/R/etc/configure = rwxr-xr-x -jre/languages/R/etc/ffibuildtype = rw-r--r-- -jre/languages/R/etc/repositories = rw-r--r-- -jre/languages/R/etc/Renviron.in = rw-r--r-- -jre/languages/R/etc/ldpaths.in = rw-r--r-- -jre/languages/R/etc/VERSION = rw-r--r-- -jre/languages/R/etc/Makeconf = rw-r--r-- -jre/languages/R/etc/Renviron = rw-r--r-- -jre/languages/R/etc/edMakeconf.etc = rw-r--r-- -jre/languages/R/etc/javaconf = rw-r--r-- -jre/languages/R/etc/tools/GETVERSION = rw-r--r-- -jre/languages/R/etc/tools/ldAIX4 = rw-r--r-- -jre/languages/R/etc/tools/copy-if-change = rw-r--r-- -jre/languages/R/etc/tools/install-sh = rwxr-xr-x -jre/languages/R/etc/tools/help2man.pl = rw-r--r-- -jre/languages/R/etc/tools/config.rpath = rwxr-xr-x -jre/languages/R/etc/tools/ltmain.sh = rw-r--r-- -jre/languages/R/etc/tools/link-recommended = rwxr-xr-x -jre/languages/R/etc/tools/Makefile = rw-r--r-- -jre/languages/R/etc/tools/config.guess = rwxr-xr-x -jre/languages/R/etc/tools/missing = rwxr-xr-x -jre/languages/R/etc/tools/README = rw-r--r-- -jre/languages/R/etc/tools/GETCONFIG = rw-r--r-- -jre/languages/R/etc/tools/config.sub = rwxr-xr-x -jre/languages/R/etc/tools/GETMAKEVAL = rwxr-xr-x -jre/languages/R/etc/tools/updatefat = rwxr-xr-x -jre/languages/R/etc/tools/install-info.pl = rw-r--r-- -jre/languages/R/etc/tools/move-if-change = rw-r--r-- -jre/languages/R/etc/tools/getsp.java = rw-r--r-- -jre/languages/R/etc/tools/Makefile.in = rw-r--r-- -jre/languages/R/etc/tools/rsync-recommended = rwxr-xr-x -jre/languages/R/etc/tools/GETDISTNAME = rwxr-xr-x -jre/languages/R/etc/tools/mdate-sh = rwxr-xr-x -jre/languages/R/etc/m4/ltversion.m4 = rw-r--r-- -jre/languages/R/etc/m4/libtool.m4 = rw-r--r-- -jre/languages/R/etc/m4/ltoptions.m4 = rw-r--r-- -jre/languages/R/etc/m4/cairo.m4 = rw-r--r-- -jre/languages/R/etc/m4/ltsugar.m4 = rw-r--r-- -jre/languages/R/etc/m4/Makefile = rw-r--r-- -jre/languages/R/etc/m4/stat-time.m4 = rw-r--r-- -jre/languages/R/etc/m4/README = rw-r--r-- -jre/languages/R/etc/m4/bigendian.m4 = rw-r--r-- -jre/languages/R/etc/m4/codeset.m4 = rw-r--r-- -jre/languages/R/etc/m4/gettext.m4 = rw-r--r-- -jre/languages/R/etc/m4/R.m4 = rw-r--r-- -jre/languages/R/etc/m4/cxx_11.m4 = rw-r--r-- -jre/languages/R/etc/m4/clibs.m4 = rw-r--r-- -jre/languages/R/etc/m4/gettext-lib.m4 = rw-r--r-- -jre/languages/R/etc/m4/Makefile.in = rw-r--r-- -jre/languages/R/etc/m4/lt~obsolete.m4 = rw-r--r-- -jre/languages/R/etc/m4/openmp.m4 = rw-r--r-- -jre/languages/R/etc/src/include/config.h.in = rw-r--r-- -jre/languages/R/share/encodings/character-sets = rw-r--r-- -jre/languages/R/share/encodings/Adobe-glyphlist = rw-r--r-- -jre/languages/R/share/R/tests-startup.R = rw-r--r-- -jre/languages/R/share/R/examples-header.R = rw-r--r-- -jre/languages/R/share/R/examples-footer.R = rw-r--r-- -jre/languages/R/share/R/REMOVE.R = rw-r--r-- -jre/languages/R/share/R/nspackloader.R = rw-r--r-- -jre/languages/R/share/java/README = rw-r--r-- -jre/languages/R/share/java/getsp.class = rw-r--r-- -jre/languages/R/share/make/shlib.mk = rw-r--r-- -jre/languages/R/share/make/check_vars_ini.mk = rw-r--r-- -jre/languages/R/share/make/lazycomp.mk = rw-r--r-- -jre/languages/R/share/make/winshlib.mk = rw-r--r-- -jre/languages/R/share/make/config.mk = rw-r--r-- -jre/languages/R/share/make/clean.mk = rw-r--r-- -jre/languages/R/share/make/vars.mk = rw-r--r-- -jre/languages/R/share/make/basepkg.mk = rw-r--r-- -jre/languages/R/share/make/check_vars_out.mk = rw-r--r-- -jre/languages/R/share/Rd/macros/system.Rd = rw-r--r-- -jre/languages/R/doc/COPYRIGHTS = rw-r--r-- -jre/languages/R/doc/BioC_mirrors.csv = rw-r--r-- -jre/languages/R/doc/NEWS.Rd = rw-r--r-- -jre/languages/R/doc/NEWS.pdf = rw-r--r-- -jre/languages/R/doc/R.aux = rw-r--r-- -jre/languages/R/doc/AUTHORS = rw-r--r-- -jre/languages/R/doc/Makefile = rw-r--r-- -jre/languages/R/doc/FAQ = rw-r--r-- -jre/languages/R/doc/RESOURCES = rw-r--r-- -jre/languages/R/doc/Rscript.1 = rw-r--r-- -jre/languages/R/doc/CRAN_mirrors.csv = rw-r--r-- -jre/languages/R/doc/NEWS.2 = rw-r--r-- -jre/languages/R/doc/COPYING = rw-r--r-- -jre/languages/R/doc/NEWS.rds = rw-r--r-- -jre/languages/R/doc/NEWS = rw-r--r-- -jre/languages/R/doc/NEWS.2.Rd = rw-r--r-- -jre/languages/R/doc/THANKS = rw-r--r-- -jre/languages/R/doc/KEYWORDS = rw-r--r-- -jre/languages/R/doc/Makefile.in = rw-r--r-- -jre/languages/R/doc/Makefile.win = rw-r--r-- -jre/languages/R/doc/R.1 = rw-r--r-- -jre/languages/R/doc/NEWS.0 = rw-r--r-- -jre/languages/R/doc/KEYWORDS.db = rw-r--r-- -jre/languages/R/doc/NEWS.1 = rw-r--r-- -jre/languages/R/doc/html/favicon.ico = rw-r--r-- -jre/languages/R/doc/html/index.html = rw-r--r-- -jre/languages/R/doc/html/about.html = rw-r--r-- -jre/languages/R/doc/html/up.jpg = rw-r--r-- -jre/languages/R/doc/html/Makefile = rw-r--r-- -jre/languages/R/doc/html/packages.html = rw-r--r-- -jre/languages/R/doc/html/NEWS.2.html = rw-r--r-- -jre/languages/R/doc/html/R-admin.html = rw-r--r-- -jre/languages/R/doc/html/index-default.html = rw-r--r-- -jre/languages/R/doc/html/NEWS.html = rw-r--r-- -jre/languages/R/doc/html/resources.html = rw-r--r-- -jre/languages/R/doc/html/left.jpg = rw-r--r-- -jre/languages/R/doc/html/Notes = rw-r--r-- -jre/languages/R/doc/html/logo.jpg = rw-r--r-- -jre/languages/R/doc/html/R.css = rw-r--r-- -jre/languages/R/doc/html/Rlogo.svg = rw-r--r-- -jre/languages/R/doc/html/Search.html = rw-r--r-- -jre/languages/R/doc/html/Rlogo.pdf = rw-r--r-- -jre/languages/R/doc/html/SearchOn.html = rw-r--r-- -jre/languages/R/doc/html/Makefile.in = rw-r--r-- -jre/languages/R/doc/html/right.jpg = rw-r--r-- -jre/languages/R/doc/html/packages-head-utf8.html = rw-r--r-- -jre/languages/R/doc/manual/R-exts.texi = rw-r--r-- -jre/languages/R/doc/manual/pdfcolor.tex = rw-r--r-- -jre/languages/R/doc/manual/refman.top = rw-r--r-- -jre/languages/R/doc/manual/ISBN = rw-r--r-- -jre/languages/R/doc/manual/resources.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile = rw-r--r-- -jre/languages/R/doc/manual/version.texi = rw-r--r-- -jre/languages/R/doc/manual/R-defs.texi = rw-r--r-- -jre/languages/R/doc/manual/R-exts.c = rw-r--r-- -jre/languages/R/doc/manual/rw-FAQ.texi = rw-r--r-- -jre/languages/R/doc/manual/R-FAQ.texi = rw-r--r-- -jre/languages/R/doc/manual/R-intro.R = rw-r--r-- -jre/languages/R/doc/manual/quot.sed = rw-r--r-- -jre/languages/R/doc/manual/README = rw-r--r-- -jre/languages/R/doc/manual/Rfaq.css = rw-r--r-- -jre/languages/R/doc/manual/refman.bot = rw-r--r-- -jre/languages/R/doc/manual/R-intro.texi = rw-r--r-- -jre/languages/R/doc/manual/stamp-images-html = rw-r--r-- -jre/languages/R/doc/manual/dir = rw-r--r-- -jre/languages/R/doc/manual/R-data.texi = rw-r--r-- -jre/languages/R/doc/manual/epsf.tex = rw-r--r-- -jre/languages/R/doc/manual/Rman.css = rw-r--r-- -jre/languages/R/doc/manual/R-ints.texi = rw-r--r-- -jre/languages/R/doc/manual/R-exts.R = rw-r--r-- -jre/languages/R/doc/manual/R-admin.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile.in = rw-r--r-- -jre/languages/R/doc/manual/R-lang.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile.win = rw-r--r-- -jre/languages/R/doc/manual/images/hist.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/hist.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig12.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig11.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/fig11.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig12.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ecdf.png = rw-r--r-- -jre/languages/R/doc/manual/images/ice.png = rw-r--r-- -jre/languages/R/doc/manual/images/QQ.png = rw-r--r-- -jre/languages/R/doc/manual/images/QQ.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ecdf.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ice.pdf = rw-r--r-- -jre/languages/R/jline.jar = rw-r--r-- -jre/languages/R/antlr4.jar = rw-r--r-- -jre/languages/R/xz-1.8.jar = rw-r--r-- -jre/languages/R/fastr-launcher.jar = rw-r--r-- -jre/languages/R/bin/exec/R = rwxr-xr-x -jre/languages/R/bin/Rscript = rwxr-xr-x -jre/languages/R/3rd_party_licenses_fastr.txt = rw-r--r-- -jre/languages/R/native-image.properties = rw-r--r-- -jre/languages/R/README_FASTR = rw-r--r-- -jre/languages/R/LICENSE_FASTR = rw-r--r-- -LICENSE_FASTR = rwxrwxrwx -3rd_party_licenses_fastr.txt = rwxrwxrwx -bin/Rscript = rwxrwxrwx -bin/R = rwxrwxrwx -jre/languages/R/release = rw-rw-r-- -jre/bin/Rscript = rwxrwxrwx -jre/bin/R = rwxrwxrwx \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/symlinks deleted file mode 100644 index 0aeecbe46387..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/META-INF/symlinks +++ /dev/null @@ -1,3 +0,0 @@ -LICENSE_FASTR = jre/languages/R/LICENSE_FASTR -bin/R = ../jre/bin/R -jre/bin/R = ../languages/R/bin/R \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/LICENSE_FASTR b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/LICENSE_FASTR deleted file mode 100644 index 54975fbea0e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/LICENSE_FASTR +++ /dev/null @@ -1,720 +0,0 @@ -Product License - GraalVM Community Edition 1.0 R Language Component - -This is a release of GraalVM Community Edition 1.0 R Language Component. This -particular copy of the software is released under version 3 of GNU General -Public License. - -Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved - -=========================================================================== - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - -=========================================================================== - - WRITTEN OFFER FOR SOURCE CODE -For any software that you receive from Oracle in binary form which is licensed -under an open source license that gives you the right to receive the source -code for that binary, you can obtain a copy of the applicable source code by -visiting http://www.oracle.com/goto/opensourcecode. If the source code for the -binary was not provided to you with the binary, you can also receive a copy of -the source code on physical media by submitting a written request to the -address listed below or by sending an email to Oracle using the following link: - http://www.oracle.com/goto/opensourcecode/request. - -Oracle America, Inc. -Attn: Senior Vice President -Development and Engineering Legal -500 Oracle Parkway, 10th Floor -Redwood Shores, CA 94065 - -Your request should include: - • The name of the binary for which you are requesting the source code - • The name and version number of the Oracle product containing the binary - • The date you received the Oracle product - • Your name - • Your company name (if applicable) - • Your return mailing address and email, and - • A telephone number in the event we need to reach you. - -We may charge you a fee to cover the cost of physical media and processing. -Your request must be sent - a. within three (3) years of the date you received the Oracle product that -included the binary that is the subject of your request, or - b. in the case of code licensed under the GPL v3 for as long as Oracle -offers spare parts or customer support for that product model. - -=========================================================================== diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/README_FASTR b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/README_FASTR deleted file mode 100644 index a5283f739238..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/README_FASTR +++ /dev/null @@ -1,70 +0,0 @@ -[![Join the chat at https://gitter.im/graalvm/graal-core](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/graalvm/graal-core?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -A high-performance implementation of the R programming language, built on GraalVM. - -FastR aims to be: -* [efficient](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#4ab6): executing R language scripts faster than any other R runtime -* [polyglot](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#0f5c): allowing [polyglot interoperability](https://www.graalvm.org/docs/reference-manual/polyglot/) with other languages in the GraalVM ecosystem. -* [compatible](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#fff5): providing support for existing packages and the R native interface -* [embeddable](https://github.com/graalvm/examples/tree/master/r_java_embedding): allowing integration using the R embedding API or the GraalVM polyglot embedding SDK - - -The screenshot below shows Java application with embedded FastR engine. -The plot below was generated by `ggplot2` running on FastR and it shows -peak performance of the [raytracing example](http://www.tylermw.com/throwing-shade/). -The measurements were [reproduced independently](https://nextjournal.com/sdanisch/fastr-benchmark). - -![Java embedding](documentation/assets/javaui.png) -![Speedup](documentation/assets/speedup.png) - - ## Getting Started -See the documentation on the GraalVM website on how to [get GraalVM](https://www.graalvm.org/docs/getting-started/) and [install and use FastR](http://www.graalvm.org/docs/reference-manual/languages/r/). - -``` -$ $GRAALVM/bin/R -Type 'q()' to quit R. -> print("Hello R!") -[1] "Hello R!" -> -``` - -## Documentation - -The reference manual for FastR, which explains its advantages, its current limitations, compatibility and additional functionality is available on the [GraalVM website](http://www.graalvm.org/docs/reference-manual/languages/r/). - -Further documentation, including contributor/developer-oriented information, is in the [documentation folder](documentation/Index.md) of this repository. - -## Current Status - -The goal of FastR is to be a drop-in replacement for GNU-R, the reference implementation of the R language. -FastR faithfully implements the R language, and any difference in behavior is considered to be a bug. - -FastR is capable of running binary R packages built for GNU-R as long as those packages properly use the R extensions C API (for best results, it is recommended to install R packages from source). -FastR supports R graphics via the grid package and packages based on grid (like lattice and ggplot2). -We are currently working towards support for the base graphics package. -FastR currently supports many of the popular R packages, such as ggplot2, jsonlite, testthat, assertthat, knitr, Shiny, Rcpp, rJava, quantmod and more… - -Moreover, support for dplyr and data.table are on the way. -We are actively monitoring and improving FastR support for the most popular packages published on CRAN including all the tidyverse packages. -However, one should take into account the experimental state of FastR, there can be packages that are not compatible yet, and if you try it on a complex R application, it can stumble on those. - -## Stay connected with the community - -See [graalvm.org/community](https://www.graalvm.org/community/) on how to stay connected with the development community. -The discussion on [gitter](https://gitter.im/graalvm/graal-core) is a good way to get in touch with us. - -We would like to grow the FastR open-source community to provide a free R implementation atop the Truffle/Graal stack. -We encourage contributions, and invite interested developers to join in. -Prospective contributors need to sign the [Oracle Contributor Agreement (OCA)](http://www.oracle.com/technetwork/community/oca-486395.html). -The access point for contributions, issues and questions about FastR is the [GitHub repository](https://github.com/oracle/fastr). - -## Authors - -FastR is developed by Oracle Labs and is based on [the GNU-R runtime](http://www.r-project.org/). -It contains contributions by researchers at Purdue University ([purdue-fastr](https://github.com/allr/purdue-fastr)), Northeastern University, JKU Linz, TU Dortmund and TU Berlin. - -## License - -FastR is available under a GPLv3 license. - - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/doc/THANKS b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/doc/THANKS deleted file mode 100644 index 6f8eb3ee226a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/doc/THANKS +++ /dev/null @@ -1,70 +0,0 @@ -R would not be what it is today without the invaluable help of these -people outside of the R core team, who contributed by donating code, bug -fixes and documentation: - -Valerio Aimale, Suharto Anggono, Thomas Baier, Henrik Bengtsson, Roger Bivand, -Ben Bolker, David Brahm, G"oran Brostr"om, Patrick Burns, Vince Carey, -Saikat DebRoy, Matt Dowle, Brian D'Urso, Lyndon Drake, Dirk Eddelbuettel, -Claus Ekstrom, Sebastian Fischmeister, John Fox, Paul Gilbert, -Yu Gong, Gabor Grothendieck, Frank E Harrell Jr, Peter M. Haverty, -Torsten Hothorn, Robert King, Kjetil Kjernsmo, Roger Koenker, Philippe Lambert, -Jan de Leeuw, Jim Lindsey, Patrick Lindsey, Catherine Loader, -Gordon Maclean, John Maindonald, David Meyer, Ei-ji Nakama, -Jens Oehlschaegel, Steve Oncley, Richard O'Keefe, Hubert Palme, -Roger D. Peng, Jose' C. Pinheiro, Tony Plate, Anthony Rossini, -Jonathan Rougier, Petr Savicky, Guenther Sawitzki, Marc Schwartz, -Arun Srinivasan, Detlef Steuer, Bill Simpson, Gordon Smyth, Adrian Trapletti, -Terry Therneau, Rolf Turner, Bill Venables, Gregory R. Warnes, -Andreas Weingessel, Morten Welinder, James Wettenhall, Simon Wood, and -Achim Zeileis. - -Others have written code that has been adopted by R and is -acknowledged in the code files, including - -J. D. Beasley, David J. Best, Richard Brent, Kevin Buhr, Michael -A. Covington, Bill Cleveland, Robert Cleveland,, G. W. Cran, -C. G. Ding, Ulrich Drepper, Paul Eggert, J. O. Evans, David M. Gay, -H. Frick, G. W. Hill, Richard H. Jones, Eric Grosse, Shelby Haberman, -Bruno Haible, John Hartigan, Andrew Harvey, Trevor Hastie, Min Long -Lam, George Marsaglia, K. J. Martin, Gordon Matzigkeit, -C. R. Mckenzie, Jean McRae, Cyrus Mehta, Fionn Murtagh, John C. Nash, -Finbarr O'Sullivan, R. E. Odeh, William Patefield, Nitin Patel, Alan -Richardson, D. E. Roberts, Patrick Royston, Russell Lenth, Ming-Jen -Shyu, Richard C. Singleton, S. G. Springer, Supoj Sutanthavibul, Irma -Terpenning, G. E. Thomas, Rob Tibshirani, Wai Wan Tsang, Berwin -Turlach, Gary V. Vaughan, Michael Wichura, Jingbo Wang, M. A. Wong, -and the Free Software Foundation (for autoconf code and utilities). -See also files under src/extras. - -Many more, too numerous to mention here, have contributed by sending bug -reports and suggesting various improvements. - -Simon Davies whilst at the University of Auckland wrote the original -version of glm(). - -Julian Harris and Wing Kwong (Tiki) Wan whilst at the University of -Auckland assisted Ross Ihaka with the original Macintosh port. - -R was inspired by the S environment which has been principally -developed by John Chambers, with substantial input from Douglas Bates, -Rick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and -Allan Wilks. - -A special debt is owed to John Chambers who has graciously contributed -advice and encouragement in the early days of R and later became a -member of the core team. - - - -The R Foundation may decide to give out @R-project.org -email addresses to contributors to the R Project (even without making them -members of the R Foundation) when in the view of the R Foundation this -would help advance the R project. - -The R Core Group, Roger Bivand, Jennifer Bryan, Di Cook, Dirk Eddelbuettel, -John Fox, Bettina Grün, Frank Harrell, Torsten Hothorn, Stefano Iacus, -Julie Josse, Balasubramanian Narasimhan, Marc Schwartz, Heather Turner, -Bill Venables, Hadley Wickham and Achim Zeileis are the ordinary members of -the R Foundation. -In addition, David Meyer and Simon Wood are also e-addressable by -.@R-project.org. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/include/linked b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/include/linked deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/library/utils/DESCRIPTION b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/library/utils/DESCRIPTION deleted file mode 100644 index e8a417ec3fe6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/library/utils/DESCRIPTION +++ /dev/null @@ -1,11 +0,0 @@ -Package: utils -Version: 3.5.1 -Priority: base -Title: The R Utils Package -Author: R Core Team and contributors worldwide -Maintainer: R Core Team -Description: R utility functions. -License: Part of R 3.5.1 -Suggests: methods, xml2, commonmark -NeedsCompilation: yes -Built: R 3.5.1; x86_64-apple-darwin18.2.0; 2019-04-02 04:04:54 UTC; unix diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/native-image.properties deleted file mode 100644 index 0b896fe5ce53..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/native-image.properties +++ /dev/null @@ -1,28 +0,0 @@ -# This file contains native-image arguments needed to fastr -# - -ImageName = RMain - -Requires = tool:nfi \ - tool:chromeinspector \ - tool:nfi \ - tool:profiler - -JavaArgs = \ - -Dfastr.resource.factory.class=com.oracle.truffle.r.nodes.builtin.EagerResourceHandlerFactory \ - -Dfastr.internal.usemxbeans=false \ - -Dfastr.internal.usenativeeventloop=false \ - -Dfastr.internal.defaultdownloadmethod=wget \ - -Dfastr.internal.ignorejvmargs=true \ - -Dfastr.use.remote.grid.awt.device=true - -LauncherClass = com.oracle.truffle.r.launcher.RMain -LauncherClassPath = lib/graalvm/launcher-common.jar:languages/R/fastr-launcher.jar - -Args = --enable-http \ - -H:MaxRuntimeCompileMethods=8000 \ - -H:+UnlockExperimentalVMOptions \ - -H:-TruffleCheckFrameImplementation \ - -H:+TruffleCheckNeverPartOfCompilation \ - -H:-UseServiceLoaderFeature \ - -H:-UnlockExperimentalVMOptions diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/release deleted file mode 100644 index eb822705c23a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=macos -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/share/java/README b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/share/java/README deleted file mode 100644 index 6201c0580eb8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.0.1.0/jre/languages/R/share/java/README +++ /dev/null @@ -1,3 +0,0 @@ -getsp.class has source tools/getsp.java. - -It is installed for use by R CMD javareconf. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/MANIFEST.MF deleted file mode 100644 index d95363e1eca9..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,24 +0,0 @@ -Bundle-Name: FastR -Bundle-Symbolic-Name: org.graalvm.R -Bundle-Version: 1.1.0.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.1.0.0 - )(os_name=macos)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/R -x-GraalVM-Message-PostInst: NOTES:\n---------------\nSome R packages nee - d a system-dependent configuration before they can be installed. A gener - ic configuration that works out of the box in most cases is provided by - default. If you wish to fine-tune the configuration to your system or sh - ould you encounter any issues during R package installation, try running - the following script that adjusts the configuration to your system: \n - ${graalvm_home}/jre/languages/R/bin/configure_fastr\n\nThe R componen - t comes without native image by default. If you wish to build the native - image, which provides faster startup, but slightly slower peak performa - nce, then run the following:\n ${graalvm_home}/jre/languages/R/bin/ins - tall_r_native_image\n\nThe native image is then used by default. Pass '- - -jvm' flag to the R or Rscript launcher to use JVM instead of the native - image. Note that the native image is not stable yet and is intended for - evaluation purposes and experiments. Some features may not work when th - e native image is installed, most notably the --polyglot switch. The nat - ive image can be uninstalled using the installation script with 'uninsta - ll' argument.\n\nSee http://www.graalvm.org/docs/reference-manual/langua - ges/r for more. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/permissions deleted file mode 100644 index 14fe1475669d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/permissions +++ /dev/null @@ -1,1622 +0,0 @@ -jre/languages/R/bin/R = rwxr-xr-x -jre/languages/R/bin/Rdconv = rwxr-xr-x -jre/languages/R/bin/SHLIB = rwxr-xr-x -jre/languages/R/bin/COMPILE = rwxr-xr-x -jre/languages/R/bin/LINK = rwxr-xr-x -jre/languages/R/bin/Sweave = rwxr-xr-x -jre/languages/R/bin/BATCH = rwxr-xr-x -jre/languages/R/bin/install_r_native_image = rwxr-xr-x -jre/languages/R/bin/f77_f2c = rwxr-xr-x -jre/languages/R/bin/build = rwxr-xr-x -jre/languages/R/bin/mkinstalldirs = rwxr-xr-x -jre/languages/R/bin/Rdiff = rwxr-xr-x -jre/languages/R/bin/check = rwxr-xr-x -jre/languages/R/bin/Stangle = rwxr-xr-x -jre/languages/R/bin/pager = rwxr-xr-x -jre/languages/R/include/S.h = rw-r--r-- -jre/languages/R/include/Rinternals.h = rw-r--r-- -jre/languages/R/include/Makefile = rw-r--r-- -jre/languages/R/include/Rembedded.h = rw-r--r-- -jre/languages/R/include/Rconfig.h = rw-r--r-- -jre/languages/R/include/Rdefines.h = rw-r--r-- -jre/languages/R/include/linked = rw-r--r-- -jre/languages/R/include/Rmath.h = rw-r--r-- -jre/languages/R/include/R.h = rw-r--r-- -jre/languages/R/include/Rversion.h = rw-r--r-- -jre/languages/R/include/Rinterface.h = rw-r--r-- -jre/languages/R/include/R_ext/GraphicsEngine.h = rw-r--r-- -jre/languages/R/include/R_ext/R-ftp-http.h = rw-r--r-- -jre/languages/R/include/R_ext/Error.h = rw-r--r-- -jre/languages/R/include/R_ext/Itermacros.h = rw-r--r-- -jre/languages/R/include/R_ext/Utils.h = rw-r--r-- -jre/languages/R/include/R_ext/stats_stubs.h = rw-r--r-- -jre/languages/R/include/R_ext/GetX11Image.h = rw-r--r-- -jre/languages/R/include/R_ext/GraphicsDevice.h = rw-r--r-- -jre/languages/R/include/R_ext/Callbacks.h = rw-r--r-- -jre/languages/R/include/R_ext/Rdynload.h = rw-r--r-- -jre/languages/R/include/R_ext/Parse.h = rw-r--r-- -jre/languages/R/include/R_ext/RS.h = rw-r--r-- -jre/languages/R/include/R_ext/BLAS.h = rw-r--r-- -jre/languages/R/include/R_ext/Arith.h = rw-r--r-- -jre/languages/R/include/R_ext/Boolean.h = rw-r--r-- -jre/languages/R/include/R_ext/Applic.h = rw-r--r-- -jre/languages/R/include/R_ext/Linpack.h = rw-r--r-- -jre/languages/R/include/R_ext/Constants.h = rw-r--r-- -jre/languages/R/include/R_ext/Riconv.h = rw-r--r-- -jre/languages/R/include/R_ext/RStartup.h = rw-r--r-- -jre/languages/R/include/R_ext/Print.h = rw-r--r-- -jre/languages/R/include/R_ext/QuartzDevice.h = rw-r--r-- -jre/languages/R/include/R_ext/libextern.h = rw-r--r-- -jre/languages/R/include/R_ext/MathThreads.h = rw-r--r-- -jre/languages/R/include/R_ext/Memory.h = rw-r--r-- -jre/languages/R/include/R_ext/Connections.h = rw-r--r-- -jre/languages/R/include/R_ext/PrtUtil.h = rw-r--r-- -jre/languages/R/include/R_ext/Altrep.h = rw-r--r-- -jre/languages/R/include/R_ext/Rallocators.h = rw-r--r-- -jre/languages/R/include/R_ext/Visibility.h = rw-r--r-- -jre/languages/R/include/R_ext/stats_package.h = rw-r--r-- -jre/languages/R/include/R_ext/Complex.h = rw-r--r-- -jre/languages/R/include/R_ext/Lapack.h = rw-r--r-- -jre/languages/R/include/R_ext/Random.h = rw-r--r-- -jre/languages/R/include/R_ext/eventloop.h = rw-r--r-- -jre/languages/R/lib/libgfortran.dylib = rwxrwxrwx -jre/languages/R/lib/libz.dylib = rwxrwxrwx -jre/languages/R/lib/libpcre.1.dylib = rw-r--r-- -jre/languages/R/lib/libRblas.dylib = rwxr-xr-x -jre/languages/R/lib/libpcre.dylib = rwxrwxrwx -jre/languages/R/lib/libgfortran.3.dylib = rw-r--r-- -jre/languages/R/lib/libgcc_s.dylib = rwxrwxrwx -jre/languages/R/lib/libR.dylib = rwxr-xr-x -jre/languages/R/lib/libquadmath.0.dylib = rw-r--r-- -jre/languages/R/lib/libz.1.dylib = rw-r--r-- -jre/languages/R/lib/libgcc_s.1.dylib = rw-r--r-- -jre/languages/R/lib/libRlapack.dylib = rwxr-xr-x -jre/languages/R/lib/libquadmath.dylib = rwxrwxrwx -jre/languages/R/library/MASS/CITATION = rw-r--r-- -jre/languages/R/library/MASS/NAMESPACE = rw-r--r-- -jre/languages/R/library/MASS/DESCRIPTION = rw-r--r-- -jre/languages/R/library/MASS/NEWS = rw-r--r-- -jre/languages/R/library/MASS/INDEX = rw-r--r-- -jre/languages/R/library/MASS/R/profiles.R = rw-r--r-- -jre/languages/R/library/MASS/R/write.matrix.R = rw-r--r-- -jre/languages/R/library/MASS/R/MASS.rdx = rw-r--r-- -jre/languages/R/library/MASS/R/corresp.R = rw-r--r-- -jre/languages/R/library/MASS/R/fitdistr.R = rw-r--r-- -jre/languages/R/library/MASS/R/sammon.R = rw-r--r-- -jre/languages/R/library/MASS/R/logtrans.R = rw-r--r-- -jre/languages/R/library/MASS/R/MASS = rw-r--r-- -jre/languages/R/library/MASS/R/MASS.rdb = rw-r--r-- -jre/languages/R/library/MASS/R/dose.p.R = rw-r--r-- -jre/languages/R/library/MASS/R/stdres.R = rw-r--r-- -jre/languages/R/library/MASS/R/enlist.R = rw-r--r-- -jre/languages/R/library/MASS/R/add.R = rw-r--r-- -jre/languages/R/library/MASS/R/neg.bin.R = rw-r--r-- -jre/languages/R/library/MASS/R/contr.sdif.R = rw-r--r-- -jre/languages/R/library/MASS/R/misc.R = rw-r--r-- -jre/languages/R/library/MASS/R/cov.trob.R = rw-r--r-- -jre/languages/R/library/MASS/R/polr.R = rw-r--r-- -jre/languages/R/library/MASS/R/hist.scott.R = rw-r--r-- -jre/languages/R/library/MASS/R/lda.R = rw-r--r-- -jre/languages/R/library/MASS/R/stepAIC.R = rw-r--r-- -jre/languages/R/library/MASS/R/area.R = rw-r--r-- -jre/languages/R/library/MASS/R/rms.curv.R = rw-r--r-- -jre/languages/R/library/MASS/R/fractions.R = rw-r--r-- -jre/languages/R/library/MASS/R/eqscplot.R = rw-r--r-- -jre/languages/R/library/MASS/R/kde2d.R = rw-r--r-- -jre/languages/R/library/MASS/R/lm.ridge.R = rw-r--r-- -jre/languages/R/library/MASS/R/confint.R = rw-r--r-- -jre/languages/R/library/MASS/R/ucv.R = rw-r--r-- -jre/languages/R/library/MASS/R/loglm.R = rw-r--r-- -jre/languages/R/library/MASS/R/gamma.shape.R = rw-r--r-- -jre/languages/R/library/MASS/R/negexp.R = rw-r--r-- -jre/languages/R/library/MASS/R/mca.R = rw-r--r-- -jre/languages/R/library/MASS/R/rlm.R = rw-r--r-- -jre/languages/R/library/MASS/R/truehist.R = rw-r--r-- -jre/languages/R/library/MASS/R/negbin.R = rw-r--r-- -jre/languages/R/library/MASS/R/qda.R = rw-r--r-- -jre/languages/R/library/MASS/R/huber.R = rw-r--r-- -jre/languages/R/library/MASS/R/mvrnorm.R = rw-r--r-- -jre/languages/R/library/MASS/R/zzz.R = rw-r--r-- -jre/languages/R/library/MASS/R/boxcox.R = rw-r--r-- -jre/languages/R/library/MASS/R/lm.gls.R = rw-r--r-- -jre/languages/R/library/MASS/R/parcoord.R = rw-r--r-- -jre/languages/R/library/MASS/R/glmmPQL.R = rw-r--r-- -jre/languages/R/library/MASS/R/isoMDS.R = rw-r--r-- -jre/languages/R/library/MASS/R/hubers.R = rw-r--r-- -jre/languages/R/library/MASS/R/lqs.R = rw-r--r-- -jre/languages/R/library/MASS/Meta/data.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/links.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/features.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/package.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/MASS/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/MASS/html/R.css = rw-r--r-- -jre/languages/R/library/MASS/html/00Index.html = rw-r--r-- -jre/languages/R/library/MASS/libs/MASS.so = rwxr-xr-x -jre/languages/R/library/MASS/po/pl/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/en@quot/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/de/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/ko/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/po/fr/LC_MESSAGES/R-MASS.mo = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch13.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch07.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch09.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch03.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch10.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch14.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch04.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch11.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch15.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch05.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch01.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch12.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch16.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch06.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch02.R = rw-r--r-- -jre/languages/R/library/MASS/scripts/ch08.R = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/MASS/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/MASS/help/MASS.rdx = rw-r--r-- -jre/languages/R/library/MASS/help/MASS.rdb = rw-r--r-- -jre/languages/R/library/MASS/help/AnIndex = rw-r--r-- -jre/languages/R/library/MASS/help/aliases.rds = rw-r--r-- -jre/languages/R/library/MASS/help/paths.rds = rw-r--r-- -jre/languages/R/library/cluster/CITATION = rw-r--r-- -jre/languages/R/library/cluster/NEWS.Rd = rw-r--r-- -jre/languages/R/library/cluster/NAMESPACE = rw-r--r-- -jre/languages/R/library/cluster/DESCRIPTION = rw-r--r-- -jre/languages/R/library/cluster/INDEX = rw-r--r-- -jre/languages/R/library/cluster/test-tools.R = rw-r--r-- -jre/languages/R/library/cluster/R/internal.R = rw-r--r-- -jre/languages/R/library/cluster/R/clusGapGen.R = rw-r--r-- -jre/languages/R/library/cluster/R/0aaa.R = rw-r--r-- -jre/languages/R/library/cluster/R/cluster.rdb = rw-r--r-- -jre/languages/R/library/cluster/R/cluster.rdx = rw-r--r-- -jre/languages/R/library/cluster/R/cluster = rw-r--r-- -jre/languages/R/library/cluster/R/coef.R = rw-r--r-- -jre/languages/R/library/cluster/R/clara.q = rw-r--r-- -jre/languages/R/library/cluster/R/silhouette.R = rw-r--r-- -jre/languages/R/library/cluster/R/mona.q = rw-r--r-- -jre/languages/R/library/cluster/R/pam.q = rw-r--r-- -jre/languages/R/library/cluster/R/plothier.q = rw-r--r-- -jre/languages/R/library/cluster/R/fanny.q = rw-r--r-- -jre/languages/R/library/cluster/R/plotpart.q = rw-r--r-- -jre/languages/R/library/cluster/R/daisy.q = rw-r--r-- -jre/languages/R/library/cluster/R/clusGap.R = rw-r--r-- -jre/languages/R/library/cluster/R/zzz.R = rw-r--r-- -jre/languages/R/library/cluster/R/ellipsoidhull.R = rw-r--r-- -jre/languages/R/library/cluster/R/diana.q = rw-r--r-- -jre/languages/R/library/cluster/R/agnes.q = rw-r--r-- -jre/languages/R/library/cluster/Meta/data.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/links.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/features.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/package.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/cluster/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/cluster/html/R.css = rw-r--r-- -jre/languages/R/library/cluster/html/00Index.html = rw-r--r-- -jre/languages/R/library/cluster/libs/cluster.so = rwxr-xr-x -jre/languages/R/library/cluster/po/pl/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/en@quot/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/en@quot/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/de/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/de/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/ko/LC_MESSAGES/cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/ko/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/po/fr/LC_MESSAGES/R-cluster.mo = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/cluster/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/cluster/help/cluster.rdb = rw-r--r-- -jre/languages/R/library/cluster/help/cluster.rdx = rw-r--r-- -jre/languages/R/library/cluster/help/AnIndex = rw-r--r-- -jre/languages/R/library/cluster/help/aliases.rds = rw-r--r-- -jre/languages/R/library/cluster/help/paths.rds = rw-r--r-- -jre/languages/R/library/parallel/NAMESPACE = rw-r--r-- -jre/languages/R/library/parallel/DESCRIPTION = rw-r--r-- -jre/languages/R/library/parallel/INDEX = rw-r--r-- -jre/languages/R/library/parallel/R/parallel = rw-r--r-- -jre/languages/R/library/parallel/R/parallel.rdx = rw-r--r-- -jre/languages/R/library/parallel/R/parallel.rdb = rw-r--r-- -jre/languages/R/library/parallel/Meta/links.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/features.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/package.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/parallel/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/parallel/html/R.css = rw-r--r-- -jre/languages/R/library/parallel/html/00Index.html = rw-r--r-- -jre/languages/R/library/parallel/libs/parallel.so = rwxr-xr-x -jre/languages/R/library/parallel/doc/parallel.pdf = rw-r--r-- -jre/languages/R/library/parallel/help/AnIndex = rw-r--r-- -jre/languages/R/library/parallel/help/aliases.rds = rw-r--r-- -jre/languages/R/library/parallel/help/paths.rds = rw-r--r-- -jre/languages/R/library/parallel/help/parallel.rdx = rw-r--r-- -jre/languages/R/library/parallel/help/parallel.rdb = rw-r--r-- -jre/languages/R/library/tools/NAMESPACE = rw-r--r-- -jre/languages/R/library/tools/DESCRIPTION = rw-r--r-- -jre/languages/R/library/tools/INDEX = rw-r--r-- -jre/languages/R/library/tools/R/tools = rw-r--r-- -jre/languages/R/library/tools/R/tools.rdb = rw-r--r-- -jre/languages/R/library/tools/R/tools.rdx = rw-r--r-- -jre/languages/R/library/tools/R/sysdata.rdb = rw-r--r-- -jre/languages/R/library/tools/R/sysdata.rdx = rw-r--r-- -jre/languages/R/library/tools/Meta/links.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/features.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/package.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/tools/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/tools/html/R.css = rw-r--r-- -jre/languages/R/library/tools/html/00Index.html = rw-r--r-- -jre/languages/R/library/tools/libs/tools.so = rwxr-xr-x -jre/languages/R/library/tools/help/AnIndex = rw-r--r-- -jre/languages/R/library/tools/help/aliases.rds = rw-r--r-- -jre/languages/R/library/tools/help/tools.rdb = rw-r--r-- -jre/languages/R/library/tools/help/tools.rdx = rw-r--r-- -jre/languages/R/library/tools/help/paths.rds = rw-r--r-- -jre/languages/R/library/methods/NAMESPACE = rw-r--r-- -jre/languages/R/library/methods/DESCRIPTION = rw-r--r-- -jre/languages/R/library/methods/INDEX = rw-r--r-- -jre/languages/R/library/methods/R/methods = rw-r--r-- -jre/languages/R/library/methods/R/methods.rdx = rw-r--r-- -jre/languages/R/library/methods/R/methods.rdb = rw-r--r-- -jre/languages/R/library/methods/Meta/links.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/features.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/package.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/methods/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/methods/html/R.css = rw-r--r-- -jre/languages/R/library/methods/html/00Index.html = rw-r--r-- -jre/languages/R/library/methods/libs/methods.so = rwxr-xr-x -jre/languages/R/library/methods/help/AnIndex = rw-r--r-- -jre/languages/R/library/methods/help/aliases.rds = rw-r--r-- -jre/languages/R/library/methods/help/paths.rds = rw-r--r-- -jre/languages/R/library/methods/help/methods.rdx = rw-r--r-- -jre/languages/R/library/methods/help/methods.rdb = rw-r--r-- -jre/languages/R/library/boot/CITATION = rw-r--r-- -jre/languages/R/library/boot/NAMESPACE = rw-r--r-- -jre/languages/R/library/boot/bd.q = rw-r--r-- -jre/languages/R/library/boot/DESCRIPTION = rw-r--r-- -jre/languages/R/library/boot/INDEX = rw-r--r-- -jre/languages/R/library/boot/R/bootfuns.q = rw-r--r-- -jre/languages/R/library/boot/R/boot = rw-r--r-- -jre/languages/R/library/boot/R/bootpracs.q = rw-r--r-- -jre/languages/R/library/boot/R/boot.rdb = rw-r--r-- -jre/languages/R/library/boot/R/boot.rdx = rw-r--r-- -jre/languages/R/library/boot/Meta/data.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/links.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/features.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/package.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/boot/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/boot/html/R.css = rw-r--r-- -jre/languages/R/library/boot/html/00Index.html = rw-r--r-- -jre/languages/R/library/boot/po/pl/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/ru/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/en@quot/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/de/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/ko/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/po/fr/LC_MESSAGES/R-boot.mo = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/boot/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/boot/help/AnIndex = rw-r--r-- -jre/languages/R/library/boot/help/aliases.rds = rw-r--r-- -jre/languages/R/library/boot/help/paths.rds = rw-r--r-- -jre/languages/R/library/boot/help/boot.rdb = rw-r--r-- -jre/languages/R/library/boot/help/boot.rdx = rw-r--r-- -jre/languages/R/library/datasets/NAMESPACE = rw-r--r-- -jre/languages/R/library/datasets/DESCRIPTION = rw-r--r-- -jre/languages/R/library/datasets/INDEX = rw-r--r-- -jre/languages/R/library/datasets/Meta/data.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/links.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/features.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/package.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/datasets/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/datasets/html/R.css = rw-r--r-- -jre/languages/R/library/datasets/html/00Index.html = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/datasets/data/morley.tab = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/datasets/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/datasets/help/AnIndex = rw-r--r-- -jre/languages/R/library/datasets/help/aliases.rds = rw-r--r-- -jre/languages/R/library/datasets/help/paths.rds = rw-r--r-- -jre/languages/R/library/datasets/help/datasets.rdx = rw-r--r-- -jre/languages/R/library/datasets/help/datasets.rdb = rw-r--r-- -jre/languages/R/library/nnet/CITATION = rw-r--r-- -jre/languages/R/library/nnet/NAMESPACE = rw-r--r-- -jre/languages/R/library/nnet/DESCRIPTION = rw-r--r-- -jre/languages/R/library/nnet/NEWS = rw-r--r-- -jre/languages/R/library/nnet/INDEX = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.R = rw-r--r-- -jre/languages/R/library/nnet/R/nnet = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.rdx = rw-r--r-- -jre/languages/R/library/nnet/R/zzz.R = rw-r--r-- -jre/languages/R/library/nnet/R/multinom.R = rw-r--r-- -jre/languages/R/library/nnet/R/vcovmultinom.R = rw-r--r-- -jre/languages/R/library/nnet/R/nnet.rdb = rw-r--r-- -jre/languages/R/library/nnet/Meta/links.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/features.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/package.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/nnet/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/nnet/html/R.css = rw-r--r-- -jre/languages/R/library/nnet/html/00Index.html = rw-r--r-- -jre/languages/R/library/nnet/libs/nnet.so = rwxr-xr-x -jre/languages/R/library/nnet/po/pl/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/en@quot/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/de/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/ko/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/po/fr/LC_MESSAGES/R-nnet.mo = rw-r--r-- -jre/languages/R/library/nnet/help/AnIndex = rw-r--r-- -jre/languages/R/library/nnet/help/aliases.rds = rw-r--r-- -jre/languages/R/library/nnet/help/paths.rds = rw-r--r-- -jre/languages/R/library/nnet/help/nnet.rdx = rw-r--r-- -jre/languages/R/library/nnet/help/nnet.rdb = rw-r--r-- -jre/languages/R/library/utils/iconvlist = rw-r--r-- -jre/languages/R/library/utils/NAMESPACE = rw-r--r-- -jre/languages/R/library/utils/DESCRIPTION = rw-r--r-- -jre/languages/R/library/utils/INDEX = rw-r--r-- -jre/languages/R/library/utils/misc/exDIF.dif = rw-r--r-- -jre/languages/R/library/utils/misc/exDIF.csv = rw-r--r-- -jre/languages/R/library/utils/R/utils = rw-r--r-- -jre/languages/R/library/utils/R/sysdata.rdb = rw-r--r-- -jre/languages/R/library/utils/R/sysdata.rdx = rw-r--r-- -jre/languages/R/library/utils/R/utils.rdx = rw-r--r-- -jre/languages/R/library/utils/R/utils.rdb = rw-r--r-- -jre/languages/R/library/utils/Meta/links.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/features.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/package.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/utils/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/utils/html/R.css = rw-r--r-- -jre/languages/R/library/utils/html/00Index.html = rw-r--r-- -jre/languages/R/library/utils/libs/utils.so = rwxr-xr-x -jre/languages/R/library/utils/Sweave/Sweave-test-1.Rnw = rw-r--r-- -jre/languages/R/library/utils/Sweave/example-1.Rnw = rw-r--r-- -jre/languages/R/library/utils/doc/Sweave.pdf = rw-r--r-- -jre/languages/R/library/utils/help/AnIndex = rw-r--r-- -jre/languages/R/library/utils/help/aliases.rds = rw-r--r-- -jre/languages/R/library/utils/help/paths.rds = rw-r--r-- -jre/languages/R/library/utils/help/utils.rdx = rw-r--r-- -jre/languages/R/library/utils/help/utils.rdb = rw-r--r-- -jre/languages/R/library/stats4/NAMESPACE = rw-r--r-- -jre/languages/R/library/stats4/DESCRIPTION = rw-r--r-- -jre/languages/R/library/stats4/INDEX = rw-r--r-- -jre/languages/R/library/stats4/R/stats4 = rw-r--r-- -jre/languages/R/library/stats4/R/stats4.rdx = rw-r--r-- -jre/languages/R/library/stats4/R/stats4.rdb = rw-r--r-- -jre/languages/R/library/stats4/Meta/links.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/features.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/package.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/stats4/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/stats4/html/R.css = rw-r--r-- -jre/languages/R/library/stats4/html/00Index.html = rw-r--r-- -jre/languages/R/library/stats4/help/AnIndex = rw-r--r-- -jre/languages/R/library/stats4/help/aliases.rds = rw-r--r-- -jre/languages/R/library/stats4/help/paths.rds = rw-r--r-- -jre/languages/R/library/stats4/help/stats4.rdx = rw-r--r-- -jre/languages/R/library/stats4/help/stats4.rdb = rw-r--r-- -jre/languages/R/library/rpart/NEWS.Rd = rw-r--r-- -jre/languages/R/library/rpart/NAMESPACE = rw-r--r-- -jre/languages/R/library/rpart/DESCRIPTION = rw-r--r-- -jre/languages/R/library/rpart/INDEX = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.exp.R = rw-r--r-- -jre/languages/R/library/rpart/R/predict.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.class.R = rw-r--r-- -jre/languages/R/library/rpart/R/post.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpartco.R = rw-r--r-- -jre/languages/R/library/rpart/R/plotcp.R = rw-r--r-- -jre/languages/R/library/rpart/R/path.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/prune.R = rw-r--r-- -jre/languages/R/library/rpart/R/labels.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/pred.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/xpred.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/na.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/snip.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.anova.R = rw-r--r-- -jre/languages/R/library/rpart/R/text.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.control.R = rw-r--r-- -jre/languages/R/library/rpart/R/printcp.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.poisson.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart = rw-r--r-- -jre/languages/R/library/rpart/R/rsq.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/formatg.R = rw-r--r-- -jre/languages/R/library/rpart/R/prune.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.branch.R = rw-r--r-- -jre/languages/R/library/rpart/R/roc.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/snip.rpart.mouse.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.rdx = rw-r--r-- -jre/languages/R/library/rpart/R/meanvar.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.rdb = rw-r--r-- -jre/languages/R/library/rpart/R/post.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/zzz.R = rw-r--r-- -jre/languages/R/library/rpart/R/summary.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpartcallback.R = rw-r--r-- -jre/languages/R/library/rpart/R/importance.R = rw-r--r-- -jre/languages/R/library/rpart/R/residuals.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/rpart.matrix.R = rw-r--r-- -jre/languages/R/library/rpart/R/model.frame.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/print.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/R/plot.rpart.R = rw-r--r-- -jre/languages/R/library/rpart/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/data.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/links.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/features.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/package.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/rpart/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/rpart/html/R.css = rw-r--r-- -jre/languages/R/library/rpart/html/00Index.html = rw-r--r-- -jre/languages/R/library/rpart/libs/rpart.so = rwxr-xr-x -jre/languages/R/library/rpart/po/pl/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/pl/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ru/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ru/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/en@quot/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/en@quot/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/de/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/de/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ko/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/ko/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/fr/LC_MESSAGES/R-rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/po/fr/LC_MESSAGES/rpart.mo = rw-r--r-- -jre/languages/R/library/rpart/doc/index.html = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.R = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.Rnw = rw-r--r-- -jre/languages/R/library/rpart/doc/usercode.pdf = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.Rnw = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.pdf = rw-r--r-- -jre/languages/R/library/rpart/doc/longintro.R = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/rpart/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/rpart/help/AnIndex = rw-r--r-- -jre/languages/R/library/rpart/help/aliases.rds = rw-r--r-- -jre/languages/R/library/rpart/help/paths.rds = rw-r--r-- -jre/languages/R/library/rpart/help/rpart.rdx = rw-r--r-- -jre/languages/R/library/rpart/help/rpart.rdb = rw-r--r-- -jre/languages/R/library/lattice/CITATION = rw-r--r-- -jre/languages/R/library/lattice/NAMESPACE = rw-r--r-- -jre/languages/R/library/lattice/DESCRIPTION = rw-r--r-- -jre/languages/R/library/lattice/NEWS = rw-r--r-- -jre/languages/R/library/lattice/INDEX = rw-r--r-- -jre/languages/R/library/lattice/demo/intervals.R = rw-r--r-- -jre/languages/R/library/lattice/demo/panel.R = rw-r--r-- -jre/languages/R/library/lattice/demo/lattice.R = rw-r--r-- -jre/languages/R/library/lattice/demo/labels.R = rw-r--r-- -jre/languages/R/library/lattice/R/qq.R = rw-r--r-- -jre/languages/R/library/lattice/R/axis.R = rw-r--r-- -jre/languages/R/library/lattice/R/shingle.R = rw-r--r-- -jre/languages/R/library/lattice/R/settings.R = rw-r--r-- -jre/languages/R/library/lattice/R/summary.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/qqmath.R = rw-r--r-- -jre/languages/R/library/lattice/R/legend.R = rw-r--r-- -jre/languages/R/library/lattice/R/densityplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/panel.smoothscatter.R = rw-r--r-- -jre/languages/R/library/lattice/R/rfs.R = rw-r--r-- -jre/languages/R/library/lattice/R/interaction.R = rw-r--r-- -jre/languages/R/library/lattice/R/xyplot.ts.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice.rdb = rw-r--r-- -jre/languages/R/library/lattice/R/update.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/bwplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/cloud.R = rw-r--r-- -jre/languages/R/library/lattice/R/panel.superpose.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice.rdx = rw-r--r-- -jre/languages/R/library/lattice/R/panel.smooth.R = rw-r--r-- -jre/languages/R/library/lattice/R/levelplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/lattice = rw-r--r-- -jre/languages/R/library/lattice/R/common.R = rw-r--r-- -jre/languages/R/library/lattice/R/panels.R = rw-r--r-- -jre/languages/R/library/lattice/R/layout.R = rw-r--r-- -jre/languages/R/library/lattice/R/miscellaneous.R = rw-r--r-- -jre/languages/R/library/lattice/R/make.groups.R = rw-r--r-- -jre/languages/R/library/lattice/R/histogram.R = rw-r--r-- -jre/languages/R/library/lattice/R/strip.R = rw-r--r-- -jre/languages/R/library/lattice/R/xyplot.R = rw-r--r-- -jre/languages/R/library/lattice/R/scales.R = rw-r--r-- -jre/languages/R/library/lattice/R/zzz.R = rw-r--r-- -jre/languages/R/library/lattice/R/splom.R = rw-r--r-- -jre/languages/R/library/lattice/R/print.trellis.R = rw-r--r-- -jre/languages/R/library/lattice/R/tmd.R = rw-r--r-- -jre/languages/R/library/lattice/R/parallel.R = rw-r--r-- -jre/languages/R/library/lattice/Meta/data.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/links.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/features.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/package.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/lattice/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/lattice/html/R.css = rw-r--r-- -jre/languages/R/library/lattice/html/00Index.html = rw-r--r-- -jre/languages/R/library/lattice/libs/lattice.so = rwxr-xr-x -jre/languages/R/library/lattice/po/pl/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/en@quot/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/de/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/ko/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/po/fr/LC_MESSAGES/R-lattice.mo = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/lattice/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/lattice/help/AnIndex = rw-r--r-- -jre/languages/R/library/lattice/help/aliases.rds = rw-r--r-- -jre/languages/R/library/lattice/help/lattice.rdb = rw-r--r-- -jre/languages/R/library/lattice/help/lattice.rdx = rw-r--r-- -jre/languages/R/library/lattice/help/paths.rds = rw-r--r-- -jre/languages/R/library/nlme/CITATION = rw-r--r-- -jre/languages/R/library/nlme/NAMESPACE = rw-r--r-- -jre/languages/R/library/nlme/DESCRIPTION = rw-r--r-- -jre/languages/R/library/nlme/INDEX = rw-r--r-- -jre/languages/R/library/nlme/LICENCE = rw-r--r-- -jre/languages/R/library/nlme/mlbook/ch04.R = rw-r--r-- -jre/languages/R/library/nlme/mlbook/README = rw-r--r-- -jre/languages/R/library/nlme/mlbook/ch05.R = rw-r--r-- -jre/languages/R/library/nlme/R/gls.R = rw-r--r-- -jre/languages/R/library/nlme/R/simulate.R = rw-r--r-- -jre/languages/R/library/nlme/R/pdMat.R = rw-r--r-- -jre/languages/R/library/nlme/R/corStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/newFunc.R = rw-r--r-- -jre/languages/R/library/nlme/R/gnls.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.rdb = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.rdx = rw-r--r-- -jre/languages/R/library/nlme/R/VarCov.R = rw-r--r-- -jre/languages/R/library/nlme/R/lmList.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme = rw-r--r-- -jre/languages/R/library/nlme/R/reStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/newMethods.R = rw-r--r-- -jre/languages/R/library/nlme/R/zzMethods.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlsList.R = rw-r--r-- -jre/languages/R/library/nlme/R/VarCorr.R = rw-r--r-- -jre/languages/R/library/nlme/R/nlme.R = rw-r--r-- -jre/languages/R/library/nlme/R/newGenerics.R = rw-r--r-- -jre/languages/R/library/nlme/R/lme.R = rw-r--r-- -jre/languages/R/library/nlme/R/varFunc.R = rw-r--r-- -jre/languages/R/library/nlme/R/modelStruct.R = rw-r--r-- -jre/languages/R/library/nlme/R/groupedData.R = rw-r--r-- -jre/languages/R/library/nlme/Meta/data.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/links.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/features.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/package.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/nlme/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/nlme/html/R.css = rw-r--r-- -jre/languages/R/library/nlme/html/00Index.html = rw-r--r-- -jre/languages/R/library/nlme/libs/nlme.so = rwxr-xr-x -jre/languages/R/library/nlme/po/pl/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/pl/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/en@quot/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/en@quot/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/de/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/de/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/ko/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/ko/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/fr/LC_MESSAGES/R-nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/po/fr/LC_MESSAGES/nlme.mo = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch03.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch04.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/runme.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/sims.rda = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch05.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch01.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch06.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch02.R = rw-r--r-- -jre/languages/R/library/nlme/scripts/ch08.R = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/nlme/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/nlme/help/AnIndex = rw-r--r-- -jre/languages/R/library/nlme/help/aliases.rds = rw-r--r-- -jre/languages/R/library/nlme/help/nlme.rdb = rw-r--r-- -jre/languages/R/library/nlme/help/nlme.rdx = rw-r--r-- -jre/languages/R/library/nlme/help/paths.rds = rw-r--r-- -jre/languages/R/library/splines/NAMESPACE = rw-r--r-- -jre/languages/R/library/splines/DESCRIPTION = rw-r--r-- -jre/languages/R/library/splines/INDEX = rw-r--r-- -jre/languages/R/library/splines/R/splines = rw-r--r-- -jre/languages/R/library/splines/R/splines.rdb = rw-r--r-- -jre/languages/R/library/splines/R/splines.rdx = rw-r--r-- -jre/languages/R/library/splines/Meta/links.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/features.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/package.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/splines/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/splines/html/R.css = rw-r--r-- -jre/languages/R/library/splines/html/00Index.html = rw-r--r-- -jre/languages/R/library/splines/libs/splines.so = rwxr-xr-x -jre/languages/R/library/splines/help/AnIndex = rw-r--r-- -jre/languages/R/library/splines/help/aliases.rds = rw-r--r-- -jre/languages/R/library/splines/help/paths.rds = rw-r--r-- -jre/languages/R/library/splines/help/splines.rdb = rw-r--r-- -jre/languages/R/library/splines/help/splines.rdx = rw-r--r-- -jre/languages/R/library/grDevices/NAMESPACE = rw-r--r-- -jre/languages/R/library/grDevices/DESCRIPTION = rw-r--r-- -jre/languages/R/library/grDevices/INDEX = rw-r--r-- -jre/languages/R/library/grDevices/demo/hclColors.R = rw-r--r-- -jre/languages/R/library/grDevices/demo/colors.R = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices.rdb = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices.rdx = rw-r--r-- -jre/languages/R/library/grDevices/R/grDevices = rw-r--r-- -jre/languages/R/library/grDevices/Meta/links.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/features.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/package.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/grDevices/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/grDevices/html/R.css = rw-r--r-- -jre/languages/R/library/grDevices/html/00Index.html = rw-r--r-- -jre/languages/R/library/grDevices/icc/srgb = rw-r--r-- -jre/languages/R/library/grDevices/icc/srgb.flate = rw-r--r-- -jre/languages/R/library/grDevices/afm/cob_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvbo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvnbo___.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019064l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agd_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncb_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-Oblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/s050000l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkdi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/poi_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvno____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agw_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019043l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Roman.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvnb____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/sy______.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059013l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvo_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tii_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-Oblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncr_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010015l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Italic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/MustRead.html = rw-r--r-- -jre/languages/R/library/grDevices/afm/Symbol.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010033l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/com_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018015l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ncbi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkd_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-BoldItalic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018032l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_regular_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059036l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/README = rw-r--r-- -jre/languages/R/library/grDevices/afm/cmti10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059033l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ArialMT-Italic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agwo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvn_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-BoldOblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019063l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tibi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/coo_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/por_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/agdo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_symbol_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n021003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/ZapfDingbats.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/p052004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/cobo____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hvb_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Times-BoldItalic.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Helvetica-Bold.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkli____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019044l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/pobi____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tir_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018012l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/bkl_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/nci_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_boldx_italic_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/hv______.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_italic_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/c059016l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/pob_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022004l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019024l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier-BoldOblique.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010013l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/cmbxti10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/tib_____.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/b018035l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n022023l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/Courier.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/CM_boldx_10.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/n019003l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/afm/a010035l.afm.gz = rw-r--r-- -jre/languages/R/library/grDevices/libs/grDevices.so = rwxr-xr-x -jre/languages/R/library/grDevices/enc/AdobeSym.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin7.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin2.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin1.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/Greek.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1257.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1250.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/TeXtext.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/PDFDoc.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1251.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/CP1253.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/KOI8-U.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/Cyrillic.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/MacRoman.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/AdobeStd.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/KOI8-R.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/ISOLatin9.enc = rw-r--r-- -jre/languages/R/library/grDevices/enc/WinAnsi.enc = rw-r--r-- -jre/languages/R/library/grDevices/help/AnIndex = rw-r--r-- -jre/languages/R/library/grDevices/help/grDevices.rdb = rw-r--r-- -jre/languages/R/library/grDevices/help/grDevices.rdx = rw-r--r-- -jre/languages/R/library/grDevices/help/aliases.rds = rw-r--r-- -jre/languages/R/library/grDevices/help/paths.rds = rw-r--r-- -jre/languages/R/library/class/CITATION = rw-r--r-- -jre/languages/R/library/class/NAMESPACE = rw-r--r-- -jre/languages/R/library/class/DESCRIPTION = rw-r--r-- -jre/languages/R/library/class/NEWS = rw-r--r-- -jre/languages/R/library/class/INDEX = rw-r--r-- -jre/languages/R/library/class/R/class.rdb = rw-r--r-- -jre/languages/R/library/class/R/class.rdx = rw-r--r-- -jre/languages/R/library/class/R/multiedit.R = rw-r--r-- -jre/languages/R/library/class/R/SOM.R = rw-r--r-- -jre/languages/R/library/class/R/lvq.R = rw-r--r-- -jre/languages/R/library/class/R/class = rw-r--r-- -jre/languages/R/library/class/R/zzz.R = rw-r--r-- -jre/languages/R/library/class/R/knn.R = rw-r--r-- -jre/languages/R/library/class/Meta/links.rds = rw-r--r-- -jre/languages/R/library/class/Meta/features.rds = rw-r--r-- -jre/languages/R/library/class/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/class/Meta/package.rds = rw-r--r-- -jre/languages/R/library/class/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/class/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/class/html/R.css = rw-r--r-- -jre/languages/R/library/class/html/00Index.html = rw-r--r-- -jre/languages/R/library/class/libs/class.so = rwxr-xr-x -jre/languages/R/library/class/po/pl/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/en@quot/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/de/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/ko/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/po/fr/LC_MESSAGES/R-class.mo = rw-r--r-- -jre/languages/R/library/class/help/class.rdb = rw-r--r-- -jre/languages/R/library/class/help/class.rdx = rw-r--r-- -jre/languages/R/library/class/help/AnIndex = rw-r--r-- -jre/languages/R/library/class/help/aliases.rds = rw-r--r-- -jre/languages/R/library/class/help/paths.rds = rw-r--r-- -jre/languages/R/library/codetools/NAMESPACE = rw-r--r-- -jre/languages/R/library/codetools/DESCRIPTION = rw-r--r-- -jre/languages/R/library/codetools/INDEX = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.rdx = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.R = rw-r--r-- -jre/languages/R/library/codetools/R/codetools.rdb = rw-r--r-- -jre/languages/R/library/codetools/R/codetools = rw-r--r-- -jre/languages/R/library/codetools/Meta/links.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/features.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/package.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/codetools/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/codetools/html/R.css = rw-r--r-- -jre/languages/R/library/codetools/html/00Index.html = rw-r--r-- -jre/languages/R/library/codetools/help/AnIndex = rw-r--r-- -jre/languages/R/library/codetools/help/codetools.rdx = rw-r--r-- -jre/languages/R/library/codetools/help/codetools.rdb = rw-r--r-- -jre/languages/R/library/codetools/help/aliases.rds = rw-r--r-- -jre/languages/R/library/codetools/help/paths.rds = rw-r--r-- -jre/languages/R/library/spatial/CITATION = rw-r--r-- -jre/languages/R/library/spatial/PP.files = rw-r--r-- -jre/languages/R/library/spatial/NAMESPACE = rw-r--r-- -jre/languages/R/library/spatial/DESCRIPTION = rw-r--r-- -jre/languages/R/library/spatial/NEWS = rw-r--r-- -jre/languages/R/library/spatial/INDEX = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig1c.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/davis.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig1b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/cells.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pines.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/caveolae.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pereg.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/hccells.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/agter.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/eagles.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/tokyo.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/grocery.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/drumlin.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/pairfn.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/nztrees.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig2a.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/redwood.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig2b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/towns.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3b.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/stowns1.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3c.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/schools.dat = rw-r--r-- -jre/languages/R/library/spatial/ppdata/fig3a.dat = rw-r--r-- -jre/languages/R/library/spatial/R/kr.R = rw-r--r-- -jre/languages/R/library/spatial/R/zzz.R = rw-r--r-- -jre/languages/R/library/spatial/R/spatial = rw-r--r-- -jre/languages/R/library/spatial/R/spatial.rdb = rw-r--r-- -jre/languages/R/library/spatial/R/spatial.rdx = rw-r--r-- -jre/languages/R/library/spatial/R/pp.R = rw-r--r-- -jre/languages/R/library/spatial/Meta/links.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/features.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/package.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/spatial/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/spatial/html/R.css = rw-r--r-- -jre/languages/R/library/spatial/html/00Index.html = rw-r--r-- -jre/languages/R/library/spatial/libs/spatial.so = rwxr-xr-x -jre/languages/R/library/spatial/po/pl/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/en@quot/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/de/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/ko/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/po/fr/LC_MESSAGES/R-spatial.mo = rw-r--r-- -jre/languages/R/library/spatial/help/AnIndex = rw-r--r-- -jre/languages/R/library/spatial/help/aliases.rds = rw-r--r-- -jre/languages/R/library/spatial/help/paths.rds = rw-r--r-- -jre/languages/R/library/spatial/help/spatial.rdb = rw-r--r-- -jre/languages/R/library/spatial/help/spatial.rdx = rw-r--r-- -jre/languages/R/library/graphics/NAMESPACE = rw-r--r-- -jre/languages/R/library/graphics/DESCRIPTION = rw-r--r-- -jre/languages/R/library/graphics/INDEX = rw-r--r-- -jre/languages/R/library/graphics/demo/Japanese.R = rw-r--r-- -jre/languages/R/library/graphics/demo/plotmath.R = rw-r--r-- -jre/languages/R/library/graphics/demo/persp.R = rw-r--r-- -jre/languages/R/library/graphics/demo/graphics.R = rw-r--r-- -jre/languages/R/library/graphics/demo/image.R = rw-r--r-- -jre/languages/R/library/graphics/demo/Hershey.R = rw-r--r-- -jre/languages/R/library/graphics/R/graphics.rdb = rw-r--r-- -jre/languages/R/library/graphics/R/graphics.rdx = rw-r--r-- -jre/languages/R/library/graphics/R/graphics = rw-r--r-- -jre/languages/R/library/graphics/Meta/links.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/features.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/package.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/graphics/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/graphics/html/R.css = rw-r--r-- -jre/languages/R/library/graphics/html/00Index.html = rw-r--r-- -jre/languages/R/library/graphics/libs/graphics.so = rwxr-xr-x -jre/languages/R/library/graphics/help/AnIndex = rw-r--r-- -jre/languages/R/library/graphics/help/aliases.rds = rw-r--r-- -jre/languages/R/library/graphics/help/graphics.rdb = rw-r--r-- -jre/languages/R/library/graphics/help/graphics.rdx = rw-r--r-- -jre/languages/R/library/graphics/help/paths.rds = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.svg = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/pch.pdf = rw-r--r-- -jre/languages/R/library/graphics/help/figures/oma.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/oma.pdf = rw-r--r-- -jre/languages/R/library/graphics/help/figures/mai.png = rw-r--r-- -jre/languages/R/library/graphics/help/figures/mai.pdf = rw-r--r-- -jre/languages/R/library/foreign/COPYRIGHTS = rw-r--r-- -jre/languages/R/library/foreign/NAMESPACE = rw-r--r-- -jre/languages/R/library/foreign/DESCRIPTION = rw-r--r-- -jre/languages/R/library/foreign/INDEX = rw-r--r-- -jre/languages/R/library/foreign/R/read.dta.R = rw-r--r-- -jre/languages/R/library/foreign/R/read.ssd.R = rw-r--r-- -jre/languages/R/library/foreign/R/minitab.R = rw-r--r-- -jre/languages/R/library/foreign/R/dbf.R = rw-r--r-- -jre/languages/R/library/foreign/R/octave.R = rw-r--r-- -jre/languages/R/library/foreign/R/spss.R = rw-r--r-- -jre/languages/R/library/foreign/R/R_systat.R = rw-r--r-- -jre/languages/R/library/foreign/R/xport.R = rw-r--r-- -jre/languages/R/library/foreign/R/zzz.R = rw-r--r-- -jre/languages/R/library/foreign/R/read.epiinfo.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign.rdb = rw-r--r-- -jre/languages/R/library/foreign/R/Sread.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign.rdx = rw-r--r-- -jre/languages/R/library/foreign/R/arff.R = rw-r--r-- -jre/languages/R/library/foreign/R/writeForeignSAS.R = rw-r--r-- -jre/languages/R/library/foreign/R/foreign = rw-r--r-- -jre/languages/R/library/foreign/R/writeForeignCode.R = rw-r--r-- -jre/languages/R/library/foreign/Meta/links.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/features.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/package.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/foreign/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/foreign/html/R.css = rw-r--r-- -jre/languages/R/library/foreign/html/00Index.html = rw-r--r-- -jre/languages/R/library/foreign/libs/foreign.so = rwxr-xr-x -jre/languages/R/library/foreign/po/pl/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/pl/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/en@quot/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/en@quot/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/de/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/de/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/fr/LC_MESSAGES/R-foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/po/fr/LC_MESSAGES/foreign.mo = rw-r--r-- -jre/languages/R/library/foreign/files/electric.sav = rw-r--r-- -jre/languages/R/library/foreign/files/Iris.syd = rw-r--r-- -jre/languages/R/library/foreign/files/testdata.sav = rw-r--r-- -jre/languages/R/library/foreign/files/HillRace.SYD = rw-r--r-- -jre/languages/R/library/foreign/files/sids.dbf = rwxr-xr-x -jre/languages/R/library/foreign/help/AnIndex = rw-r--r-- -jre/languages/R/library/foreign/help/aliases.rds = rw-r--r-- -jre/languages/R/library/foreign/help/paths.rds = rw-r--r-- -jre/languages/R/library/foreign/help/foreign.rdb = rw-r--r-- -jre/languages/R/library/foreign/help/foreign.rdx = rw-r--r-- -jre/languages/R/library/compiler/NAMESPACE = rw-r--r-- -jre/languages/R/library/compiler/DESCRIPTION = rw-r--r-- -jre/languages/R/library/compiler/INDEX = rw-r--r-- -jre/languages/R/library/compiler/R/compiler = rw-r--r-- -jre/languages/R/library/compiler/R/compiler.rdx = rw-r--r-- -jre/languages/R/library/compiler/R/compiler.rdb = rw-r--r-- -jre/languages/R/library/compiler/Meta/links.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/features.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/package.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/compiler/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/compiler/html/R.css = rw-r--r-- -jre/languages/R/library/compiler/html/00Index.html = rw-r--r-- -jre/languages/R/library/compiler/help/AnIndex = rw-r--r-- -jre/languages/R/library/compiler/help/aliases.rds = rw-r--r-- -jre/languages/R/library/compiler/help/paths.rds = rw-r--r-- -jre/languages/R/library/compiler/help/compiler.rdx = rw-r--r-- -jre/languages/R/library/compiler/help/compiler.rdb = rw-r--r-- -jre/languages/R/library/Matrix/Copyrights = rw-r--r-- -jre/languages/R/library/Matrix/NEWS.Rd = rw-r--r-- -jre/languages/R/library/Matrix/test-tools-1.R = rw-r--r-- -jre/languages/R/library/Matrix/NAMESPACE = rw-r--r-- -jre/languages/R/library/Matrix/DESCRIPTION = rw-r--r-- -jre/languages/R/library/Matrix/INDEX = rw-r--r-- -jre/languages/R/library/Matrix/test-tools-Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/Doxyfile = rw-r--r-- -jre/languages/R/library/Matrix/test-tools.R = rw-r--r-- -jre/languages/R/library/Matrix/LICENCE = rw-r--r-- -jre/languages/R/library/Matrix/include/Matrix.h = rw-r--r-- -jre/languages/R/library/Matrix/include/Matrix_stubs.c = rw-r--r-- -jre/languages/R/library/Matrix/include/cholmod.h = rw-r--r-- -jre/languages/R/library/Matrix/R/expm.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Auxiliaries.R = rw-r--r-- -jre/languages/R/library/Matrix/R/corMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ngTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/rankMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ndenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/SparseM-conv.R = rw-r--r-- -jre/languages/R/library/Matrix/R/indMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseQR.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Tsparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ntCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/spModels.R = rw-r--r-- -jre/languages/R/library/Matrix/R/LU.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dppMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/AllClass.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Csparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/pMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ntTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/MatrixFactorization.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ddenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/AllGeneric.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/kronecker.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.rdb = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.rdx = rw-r--r-- -jre/languages/R/library/Matrix/R/not.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ngCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dpoMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/denseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/triangularMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/KhatriRao.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtrMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dspMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/bind2.R = rw-r--r-- -jre/languages/R/library/Matrix/R/abIndex.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsyMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/condest.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Rsparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lgTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/eigen.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Math.R = rw-r--r-- -jre/languages/R/library/Matrix/R/sparseVector.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dgeMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nnzero.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ltCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/zzz.R = rw-r--r-- -jre/languages/R/library/Matrix/R/CHMfactor.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Hilbert.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lsCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ltTMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Ops.R = rw-r--r-- -jre/languages/R/library/Matrix/R/nsparseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/diagMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Matrix = rw-r--r-- -jre/languages/R/library/Matrix/R/nearPD.R = rw-r--r-- -jre/languages/R/library/Matrix/R/products.R = rw-r--r-- -jre/languages/R/library/Matrix/R/dtpMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/colSums.R = rw-r--r-- -jre/languages/R/library/Matrix/R/HBMM.R = rw-r--r-- -jre/languages/R/library/Matrix/R/Summary.R = rw-r--r-- -jre/languages/R/library/Matrix/R/ldenseMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/bandSparse.R = rw-r--r-- -jre/languages/R/library/Matrix/R/lgCMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/R/symmetricMatrix.R = rw-r--r-- -jre/languages/R/library/Matrix/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/data.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/links.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/features.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/package.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/Matrix/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/Matrix/html/R.css = rw-r--r-- -jre/languages/R/library/Matrix/html/00Index.html = rw-r--r-- -jre/languages/R/library/Matrix/libs/Matrix.so = rwxr-xr-x -jre/languages/R/library/Matrix/po/pl/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/pl/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/en@quot/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/en@quot/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/de/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/de/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/ko/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/fr/LC_MESSAGES/Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/po/fr/LC_MESSAGES/R-Matrix.mo = rw-r--r-- -jre/languages/R/library/Matrix/doc/index.html = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Announce.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/Design-issues.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Comparisons.R = rw-r--r-- -jre/languages/R/library/Matrix/doc/sparseModels.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Introduction.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.pdf = rw-r--r-- -jre/languages/R/library/Matrix/doc/Intro2Matrix.Rnw = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/SPQR.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/CHOLMOD.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/SuiteSparse_config.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/UserGuides.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/AMD.txt = rw-r--r-- -jre/languages/R/library/Matrix/doc/SuiteSparse/COLAMD.txt = rw-r--r-- -jre/languages/R/library/Matrix/external/lund_a.rsa = rw-r--r-- -jre/languages/R/library/Matrix/external/CAex_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/test3comp.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/utm300.rua = rw-r--r-- -jre/languages/R/library/Matrix/external/USCounties_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/lund_a.mtx = rw-r--r-- -jre/languages/R/library/Matrix/external/wrong.mtx = rw-r--r-- -jre/languages/R/library/Matrix/external/symA.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/KNex_slots.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/symW.rda = rw-r--r-- -jre/languages/R/library/Matrix/external/pores_1.mtx = rw-r--r-- -jre/languages/R/library/Matrix/data/KNex.R = rw-r--r-- -jre/languages/R/library/Matrix/data/CAex.R = rw-r--r-- -jre/languages/R/library/Matrix/data/USCounties.R = rw-r--r-- -jre/languages/R/library/Matrix/help/AnIndex = rw-r--r-- -jre/languages/R/library/Matrix/help/aliases.rds = rw-r--r-- -jre/languages/R/library/Matrix/help/Matrix.rdb = rw-r--r-- -jre/languages/R/library/Matrix/help/Matrix.rdx = rw-r--r-- -jre/languages/R/library/Matrix/help/paths.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/NAMESPACE = rw-r--r-- -jre/languages/R/library/KernSmooth/DESCRIPTION = rw-r--r-- -jre/languages/R/library/KernSmooth/INDEX = rw-r--r-- -jre/languages/R/library/KernSmooth/R/all.R = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth.rdb = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth.rdx = rw-r--r-- -jre/languages/R/library/KernSmooth/R/KernSmooth = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/links.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/features.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/package.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/html/R.css = rw-r--r-- -jre/languages/R/library/KernSmooth/html/00Index.html = rw-r--r-- -jre/languages/R/library/KernSmooth/libs/KernSmooth.so = rwxr-xr-x -jre/languages/R/library/KernSmooth/po/pl/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/en@quot/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/de/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/ko/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/po/fr/LC_MESSAGES/R-KernSmooth.mo = rw-r--r-- -jre/languages/R/library/KernSmooth/help/AnIndex = rw-r--r-- -jre/languages/R/library/KernSmooth/help/aliases.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/help/paths.rds = rw-r--r-- -jre/languages/R/library/KernSmooth/help/KernSmooth.rdb = rw-r--r-- -jre/languages/R/library/KernSmooth/help/KernSmooth.rdx = rw-r--r-- -jre/languages/R/library/base/CITATION = rw-r--r-- -jre/languages/R/library/base/DESCRIPTION = rw-r--r-- -jre/languages/R/library/base/INDEX = rw-r--r-- -jre/languages/R/library/base/demo/scoping.R = rw-r--r-- -jre/languages/R/library/base/demo/error.catching.R = rw-r--r-- -jre/languages/R/library/base/demo/is.things.R = rw-r--r-- -jre/languages/R/library/base/demo/recursion.R = rw-r--r-- -jre/languages/R/library/base/R/Rprofile = rw-r--r-- -jre/languages/R/library/base/R/base.rdx = rw-r--r-- -jre/languages/R/library/base/R/base.rdb = rw-r--r-- -jre/languages/R/library/base/R/base = rw-r--r-- -jre/languages/R/library/base/Meta/links.rds = rw-r--r-- -jre/languages/R/library/base/Meta/features.rds = rw-r--r-- -jre/languages/R/library/base/Meta/package.rds = rw-r--r-- -jre/languages/R/library/base/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/base/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/base/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/base/html/R.css = rw-r--r-- -jre/languages/R/library/base/html/00Index.html = rw-r--r-- -jre/languages/R/library/base/libs/base.so = rwxr-xr-x -jre/languages/R/library/base/help/AnIndex = rw-r--r-- -jre/languages/R/library/base/help/aliases.rds = rw-r--r-- -jre/languages/R/library/base/help/paths.rds = rw-r--r-- -jre/languages/R/library/base/help/base.rdx = rw-r--r-- -jre/languages/R/library/base/help/base.rdb = rw-r--r-- -jre/languages/R/library/stats/COPYRIGHTS.modreg = rw-r--r-- -jre/languages/R/library/stats/NAMESPACE = rw-r--r-- -jre/languages/R/library/stats/SOURCES.ts = rw-r--r-- -jre/languages/R/library/stats/DESCRIPTION = rw-r--r-- -jre/languages/R/library/stats/INDEX = rw-r--r-- -jre/languages/R/library/stats/demo/smooth.R = rw-r--r-- -jre/languages/R/library/stats/demo/lm.glm.R = rw-r--r-- -jre/languages/R/library/stats/demo/nlm.R = rw-r--r-- -jre/languages/R/library/stats/demo/glm.vr.R = rw-r--r-- -jre/languages/R/library/stats/R/stats.rdx = rw-r--r-- -jre/languages/R/library/stats/R/stats.rdb = rw-r--r-- -jre/languages/R/library/stats/R/stats = rw-r--r-- -jre/languages/R/library/stats/Meta/links.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/features.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/package.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/stats/Meta/demo.rds = rw-r--r-- -jre/languages/R/library/stats/html/R.css = rw-r--r-- -jre/languages/R/library/stats/html/00Index.html = rw-r--r-- -jre/languages/R/library/stats/libs/stats.so = rwxr-xr-x -jre/languages/R/library/stats/help/AnIndex = rw-r--r-- -jre/languages/R/library/stats/help/aliases.rds = rw-r--r-- -jre/languages/R/library/stats/help/stats.rdx = rw-r--r-- -jre/languages/R/library/stats/help/paths.rds = rw-r--r-- -jre/languages/R/library/stats/help/stats.rdb = rw-r--r-- -jre/languages/R/library/survival/CITATION = rw-r--r-- -jre/languages/R/library/survival/COPYRIGHTS = rw-r--r-- -jre/languages/R/library/survival/NEWS.Rd = rw-r--r-- -jre/languages/R/library/survival/NAMESPACE = rw-r--r-- -jre/languages/R/library/survival/DESCRIPTION = rw-r--r-- -jre/languages/R/library/survival/INDEX = rw-r--r-- -jre/languages/R/library/survival/R/print.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/plot.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cluster.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gamma.S = rw-r--r-- -jre/languages/R/library/survival/R/aareg.taper.R = rw-r--r-- -jre/languages/R/library/survival/R/survival.rdb = rw-r--r-- -jre/languages/R/library/survival/R/pspline.R = rw-r--r-- -jre/languages/R/library/survival/R/plot.survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/print.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/survival.rdx = rw-r--r-- -jre/languages/R/library/survival/R/coxph.getdata.S = rw-r--r-- -jre/languages/R/library/survival/R/coxph.rvar.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlgam.S = rw-r--r-- -jre/languages/R/library/survival/R/survfit.matrix.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survfit.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.cfit.R = rw-r--r-- -jre/languages/R/library/survival/R/survobrien.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/tmerge.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxph.penal.R = rw-r--r-- -jre/languages/R/library/survival/R/plot.cox.zph.S = rw-r--r-- -jre/languages/R/library/survival/R/basehaz.R = rw-r--r-- -jre/languages/R/library/survival/R/format.Surv.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/normalizetime.R = rw-r--r-- -jre/languages/R/library/survival/R/survfit.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/residuals.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gammacon.S = rw-r--r-- -jre/languages/R/library/survival/R/is.na.coxph.penalty.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cch.R = rw-r--r-- -jre/languages/R/library/survival/R/lines.survfit.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/anova.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/is.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/statefig.R = rw-r--r-- -jre/languages/R/library/survival/R/survreg.control.S = rw-r--r-- -jre/languages/R/library/survival/R/survreg.distributions.S = rw-r--r-- -jre/languages/R/library/survival/R/ridge.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.null.S = rw-r--r-- -jre/languages/R/library/survival/R/pyears.R = rw-r--r-- -jre/languages/R/library/survival/R/summary.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/coxph.detail.S = rw-r--r-- -jre/languages/R/library/survival/R/print.pyears.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.wtest.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/survConcordance.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitTurnbull.S = rw-r--r-- -jre/languages/R/library/survival/R/survpenal.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/survfitCI.R = rw-r--r-- -jre/languages/R/library/survival/R/attrassign.R = rw-r--r-- -jre/languages/R/library/survival/R/ratetableold.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survfitms.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.brent.S = rw-r--r-- -jre/languages/R/library/survival/R/match.ratetable.R = rwxr-xr-x -jre/languages/R/library/survival/R/firstlib.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitcoxph.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/cipoisson.R = rw-r--r-- -jre/languages/R/library/survival/R/predict.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/lines.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survexp.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlgauss.S = rw-r--r-- -jre/languages/R/library/survival/R/print.survreg.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.S = rw-r--r-- -jre/languages/R/library/survival/R/strata.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/predict.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/yates.R = rw-r--r-- -jre/languages/R/library/survival/R/neardate.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survdiff.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/coxpenal.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/agexact.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/model.matrix.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/model.frame.survreg.R = rw-r--r-- -jre/languages/R/library/survival/R/lines.aareg.S = rw-r--r-- -jre/languages/R/library/survival/R/cox.zph.S = rw-r--r-- -jre/languages/R/library/survival/R/survfitms.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.coxph.S = rw-r--r-- -jre/languages/R/library/survival/R/survexp.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.gaussian.S = rw-r--r-- -jre/languages/R/library/survival/R/ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controlaic.S = rw-r--r-- -jre/languages/R/library/survival/R/tcut.S = rw-r--r-- -jre/languages/R/library/survival/R/dsurvreg.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/clogit.R = rw-r--r-- -jre/languages/R/library/survival/R/print.survexp.S = rw-r--r-- -jre/languages/R/library/survival/R/Surv.R = rw-r--r-- -jre/languages/R/library/survival/R/survfitKM.S = rw-r--r-- -jre/languages/R/library/survival/R/survreg.fit.S = rw-r--r-- -jre/languages/R/library/survival/R/frailty.t.S = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.survfit.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/survdiff.S = rw-r--r-- -jre/languages/R/library/survival/R/summary.ratetable.R = rw-r--r-- -jre/languages/R/library/survival/R/aeqSurv.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.coxphlist.S = rw-r--r-- -jre/languages/R/library/survival/R/finegray.R = rw-r--r-- -jre/languages/R/library/survival/R/summary.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/coxpenal.df.S = rw-r--r-- -jre/languages/R/library/survival/R/ratetableDate.R = rw-r--r-- -jre/languages/R/library/survival/R/predict.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/agreg.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/anova.survreglist.S = rw-r--r-- -jre/languages/R/library/survival/R/print.coxph.null.S = rw-r--r-- -jre/languages/R/library/survival/R/quantile.survfit.R = rw-r--r-- -jre/languages/R/library/survival/R/coxexact.fit.R = rw-r--r-- -jre/languages/R/library/survival/R/untangle.specials.S = rw-r--r-- -jre/languages/R/library/survival/R/predict.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/survConcordance.R = rw-r--r-- -jre/languages/R/library/survival/R/print.summary.coxph.penal.S = rw-r--r-- -jre/languages/R/library/survival/R/agsurv.R = rw-r--r-- -jre/languages/R/library/survival/R/frailty.controldf.S = rw-r--r-- -jre/languages/R/library/survival/R/residuals.survreg.R = rw-r--r-- -jre/languages/R/library/survival/R/survcallback.S = rw-r--r-- -jre/languages/R/library/survival/R/logLik.coxph.R = rw-r--r-- -jre/languages/R/library/survival/R/survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/survSplit.R = rw-r--r-- -jre/languages/R/library/survival/R/labels.survreg.S = rw-r--r-- -jre/languages/R/library/survival/R/survival = rw-r--r-- -jre/languages/R/library/survival/R/survregDtest.S = rw-r--r-- -jre/languages/R/library/survival/R/xtras.R = rw-r--r-- -jre/languages/R/library/survival/R/coxph.control.S = rw-r--r-- -jre/languages/R/library/survival/R/survdiff.fit.S = rw-r--r-- -jre/languages/R/library/survival/Meta/vignette.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/data.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/links.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/features.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/package.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/survival/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/survival/html/R.css = rw-r--r-- -jre/languages/R/library/survival/html/00Index.html = rw-r--r-- -jre/languages/R/library/survival/libs/survival.so = rwxr-xr-x -jre/languages/R/library/survival/doc/adjcurve.R = rw-r--r-- -jre/languages/R/library/survival/doc/adjcurve.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/adjcurve.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/index.html = rw-r--r-- -jre/languages/R/library/survival/doc/tests.R = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/multi.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/multi.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/population.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/population.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.R = rw-r--r-- -jre/languages/R/library/survival/doc/population.R = rw-r--r-- -jre/languages/R/library/survival/doc/tests.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/tests.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/compete.R = rw-r--r-- -jre/languages/R/library/survival/doc/compete.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/compete.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.R = rw-r--r-- -jre/languages/R/library/survival/doc/validate.R = rw-r--r-- -jre/languages/R/library/survival/doc/timedep.R = rw-r--r-- -jre/languages/R/library/survival/doc/validate.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/validate.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/splines.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.Rnw = rw-r--r-- -jre/languages/R/library/survival/doc/tiedtimes.pdf = rw-r--r-- -jre/languages/R/library/survival/doc/multi.R = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rds = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rdx = rw-r--r-- -jre/languages/R/library/survival/data/Rdata.rdb = rw-r--r-- -jre/languages/R/library/survival/help/survival.rdb = rw-r--r-- -jre/languages/R/library/survival/help/survival.rdx = rw-r--r-- -jre/languages/R/library/survival/help/AnIndex = rw-r--r-- -jre/languages/R/library/survival/help/aliases.rds = rw-r--r-- -jre/languages/R/library/survival/help/paths.rds = rw-r--r-- -jre/languages/R/library/grid/NAMESPACE = rw-r--r-- -jre/languages/R/library/grid/DESCRIPTION = rw-r--r-- -jre/languages/R/library/grid/INDEX = rw-r--r-- -jre/languages/R/library/grid/R/grid.rdb = rw-r--r-- -jre/languages/R/library/grid/R/grid.rdx = rw-r--r-- -jre/languages/R/library/grid/R/grid = rw-r--r-- -jre/languages/R/library/grid/Meta/links.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/features.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/nsInfo.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/package.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/hsearch.rds = rw-r--r-- -jre/languages/R/library/grid/Meta/Rd.rds = rw-r--r-- -jre/languages/R/library/grid/html/R.css = rw-r--r-- -jre/languages/R/library/grid/html/00Index.html = rw-r--r-- -jre/languages/R/library/grid/libs/grid.so = rwxr-xr-x -jre/languages/R/library/grid/doc/moveline.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/plotexample.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/saveload.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/displaylist.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/viewports.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/interactive.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/grid.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/DivByZero.txt = rw-r--r-- -jre/languages/R/library/grid/doc/rotated.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/changes.txt = rw-r--r-- -jre/languages/R/library/grid/doc/locndimn.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/frame.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/nonfinite.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/sharing.pdf = rw-r--r-- -jre/languages/R/library/grid/doc/grobs.pdf = rw-r--r-- -jre/languages/R/library/grid/help/AnIndex = rw-r--r-- -jre/languages/R/library/grid/help/aliases.rds = rw-r--r-- -jre/languages/R/library/grid/help/grid.rdb = rw-r--r-- -jre/languages/R/library/grid/help/grid.rdx = rw-r--r-- -jre/languages/R/library/grid/help/paths.rds = rw-r--r-- -jre/languages/R/etc/edMakeconf.etc.llvm = rw-r--r-- -jre/languages/R/etc/native-packages = rw-r--r-- -jre/languages/R/etc/configure.ac = rw-r--r-- -jre/languages/R/etc/Makeconf.in = rw-r--r-- -jre/languages/R/etc/ldpaths = rw-r--r-- -jre/languages/R/etc/DEFAULT_CRAN_MIRROR = rw-r--r-- -jre/languages/R/etc/configure = rwxr-xr-x -jre/languages/R/etc/ffibuildtype = rw-r--r-- -jre/languages/R/etc/repositories = rw-r--r-- -jre/languages/R/etc/Renviron.in = rw-r--r-- -jre/languages/R/etc/ldpaths.in = rw-r--r-- -jre/languages/R/etc/VERSION = rw-r--r-- -jre/languages/R/etc/Makeconf = rw-r--r-- -jre/languages/R/etc/Renviron = rw-r--r-- -jre/languages/R/etc/edMakeconf.etc = rw-r--r-- -jre/languages/R/etc/javaconf = rw-r--r-- -jre/languages/R/etc/tools/GETVERSION = rw-r--r-- -jre/languages/R/etc/tools/ldAIX4 = rw-r--r-- -jre/languages/R/etc/tools/copy-if-change = rw-r--r-- -jre/languages/R/etc/tools/install-sh = rwxr-xr-x -jre/languages/R/etc/tools/help2man.pl = rw-r--r-- -jre/languages/R/etc/tools/config.rpath = rwxr-xr-x -jre/languages/R/etc/tools/ltmain.sh = rw-r--r-- -jre/languages/R/etc/tools/link-recommended = rwxr-xr-x -jre/languages/R/etc/tools/Makefile = rw-r--r-- -jre/languages/R/etc/tools/config.guess = rwxr-xr-x -jre/languages/R/etc/tools/missing = rwxr-xr-x -jre/languages/R/etc/tools/README = rw-r--r-- -jre/languages/R/etc/tools/GETCONFIG = rw-r--r-- -jre/languages/R/etc/tools/config.sub = rwxr-xr-x -jre/languages/R/etc/tools/GETMAKEVAL = rwxr-xr-x -jre/languages/R/etc/tools/updatefat = rwxr-xr-x -jre/languages/R/etc/tools/install-info.pl = rw-r--r-- -jre/languages/R/etc/tools/move-if-change = rw-r--r-- -jre/languages/R/etc/tools/getsp.java = rw-r--r-- -jre/languages/R/etc/tools/Makefile.in = rw-r--r-- -jre/languages/R/etc/tools/rsync-recommended = rwxr-xr-x -jre/languages/R/etc/tools/GETDISTNAME = rwxr-xr-x -jre/languages/R/etc/tools/mdate-sh = rwxr-xr-x -jre/languages/R/etc/m4/ltversion.m4 = rw-r--r-- -jre/languages/R/etc/m4/libtool.m4 = rw-r--r-- -jre/languages/R/etc/m4/ltoptions.m4 = rw-r--r-- -jre/languages/R/etc/m4/cairo.m4 = rw-r--r-- -jre/languages/R/etc/m4/ltsugar.m4 = rw-r--r-- -jre/languages/R/etc/m4/Makefile = rw-r--r-- -jre/languages/R/etc/m4/stat-time.m4 = rw-r--r-- -jre/languages/R/etc/m4/README = rw-r--r-- -jre/languages/R/etc/m4/bigendian.m4 = rw-r--r-- -jre/languages/R/etc/m4/codeset.m4 = rw-r--r-- -jre/languages/R/etc/m4/gettext.m4 = rw-r--r-- -jre/languages/R/etc/m4/R.m4 = rw-r--r-- -jre/languages/R/etc/m4/cxx_11.m4 = rw-r--r-- -jre/languages/R/etc/m4/clibs.m4 = rw-r--r-- -jre/languages/R/etc/m4/gettext-lib.m4 = rw-r--r-- -jre/languages/R/etc/m4/Makefile.in = rw-r--r-- -jre/languages/R/etc/m4/lt~obsolete.m4 = rw-r--r-- -jre/languages/R/etc/m4/openmp.m4 = rw-r--r-- -jre/languages/R/etc/src/include/config.h.in = rw-r--r-- -jre/languages/R/share/encodings/character-sets = rw-r--r-- -jre/languages/R/share/encodings/Adobe-glyphlist = rw-r--r-- -jre/languages/R/share/R/tests-startup.R = rw-r--r-- -jre/languages/R/share/R/examples-header.R = rw-r--r-- -jre/languages/R/share/R/examples-footer.R = rw-r--r-- -jre/languages/R/share/R/REMOVE.R = rw-r--r-- -jre/languages/R/share/R/nspackloader.R = rw-r--r-- -jre/languages/R/share/java/README = rw-r--r-- -jre/languages/R/share/java/getsp.class = rw-r--r-- -jre/languages/R/share/make/shlib.mk = rw-r--r-- -jre/languages/R/share/make/check_vars_ini.mk = rw-r--r-- -jre/languages/R/share/make/lazycomp.mk = rw-r--r-- -jre/languages/R/share/make/winshlib.mk = rw-r--r-- -jre/languages/R/share/make/config.mk = rw-r--r-- -jre/languages/R/share/make/clean.mk = rw-r--r-- -jre/languages/R/share/make/vars.mk = rw-r--r-- -jre/languages/R/share/make/basepkg.mk = rw-r--r-- -jre/languages/R/share/make/check_vars_out.mk = rw-r--r-- -jre/languages/R/share/Rd/macros/system.Rd = rw-r--r-- -jre/languages/R/doc/COPYRIGHTS = rw-r--r-- -jre/languages/R/doc/BioC_mirrors.csv = rw-r--r-- -jre/languages/R/doc/NEWS.Rd = rw-r--r-- -jre/languages/R/doc/NEWS.pdf = rw-r--r-- -jre/languages/R/doc/R.aux = rw-r--r-- -jre/languages/R/doc/AUTHORS = rw-r--r-- -jre/languages/R/doc/Makefile = rw-r--r-- -jre/languages/R/doc/FAQ = rw-r--r-- -jre/languages/R/doc/RESOURCES = rw-r--r-- -jre/languages/R/doc/Rscript.1 = rw-r--r-- -jre/languages/R/doc/CRAN_mirrors.csv = rw-r--r-- -jre/languages/R/doc/NEWS.2 = rw-r--r-- -jre/languages/R/doc/COPYING = rw-r--r-- -jre/languages/R/doc/NEWS.rds = rw-r--r-- -jre/languages/R/doc/NEWS = rw-r--r-- -jre/languages/R/doc/NEWS.2.Rd = rw-r--r-- -jre/languages/R/doc/THANKS = rw-r--r-- -jre/languages/R/doc/KEYWORDS = rw-r--r-- -jre/languages/R/doc/Makefile.in = rw-r--r-- -jre/languages/R/doc/Makefile.win = rw-r--r-- -jre/languages/R/doc/R.1 = rw-r--r-- -jre/languages/R/doc/NEWS.0 = rw-r--r-- -jre/languages/R/doc/KEYWORDS.db = rw-r--r-- -jre/languages/R/doc/NEWS.1 = rw-r--r-- -jre/languages/R/doc/html/favicon.ico = rw-r--r-- -jre/languages/R/doc/html/index.html = rw-r--r-- -jre/languages/R/doc/html/about.html = rw-r--r-- -jre/languages/R/doc/html/up.jpg = rw-r--r-- -jre/languages/R/doc/html/Makefile = rw-r--r-- -jre/languages/R/doc/html/packages.html = rw-r--r-- -jre/languages/R/doc/html/NEWS.2.html = rw-r--r-- -jre/languages/R/doc/html/R-admin.html = rw-r--r-- -jre/languages/R/doc/html/index-default.html = rw-r--r-- -jre/languages/R/doc/html/NEWS.html = rw-r--r-- -jre/languages/R/doc/html/resources.html = rw-r--r-- -jre/languages/R/doc/html/left.jpg = rw-r--r-- -jre/languages/R/doc/html/Notes = rw-r--r-- -jre/languages/R/doc/html/logo.jpg = rw-r--r-- -jre/languages/R/doc/html/R.css = rw-r--r-- -jre/languages/R/doc/html/Rlogo.svg = rw-r--r-- -jre/languages/R/doc/html/Search.html = rw-r--r-- -jre/languages/R/doc/html/Rlogo.pdf = rw-r--r-- -jre/languages/R/doc/html/SearchOn.html = rw-r--r-- -jre/languages/R/doc/html/Makefile.in = rw-r--r-- -jre/languages/R/doc/html/right.jpg = rw-r--r-- -jre/languages/R/doc/html/packages-head-utf8.html = rw-r--r-- -jre/languages/R/doc/manual/R-exts.texi = rw-r--r-- -jre/languages/R/doc/manual/pdfcolor.tex = rw-r--r-- -jre/languages/R/doc/manual/refman.top = rw-r--r-- -jre/languages/R/doc/manual/ISBN = rw-r--r-- -jre/languages/R/doc/manual/resources.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile = rw-r--r-- -jre/languages/R/doc/manual/version.texi = rw-r--r-- -jre/languages/R/doc/manual/R-defs.texi = rw-r--r-- -jre/languages/R/doc/manual/R-exts.c = rw-r--r-- -jre/languages/R/doc/manual/rw-FAQ.texi = rw-r--r-- -jre/languages/R/doc/manual/R-FAQ.texi = rw-r--r-- -jre/languages/R/doc/manual/R-intro.R = rw-r--r-- -jre/languages/R/doc/manual/quot.sed = rw-r--r-- -jre/languages/R/doc/manual/README = rw-r--r-- -jre/languages/R/doc/manual/Rfaq.css = rw-r--r-- -jre/languages/R/doc/manual/refman.bot = rw-r--r-- -jre/languages/R/doc/manual/R-intro.texi = rw-r--r-- -jre/languages/R/doc/manual/stamp-images-html = rw-r--r-- -jre/languages/R/doc/manual/dir = rw-r--r-- -jre/languages/R/doc/manual/R-data.texi = rw-r--r-- -jre/languages/R/doc/manual/epsf.tex = rw-r--r-- -jre/languages/R/doc/manual/Rman.css = rw-r--r-- -jre/languages/R/doc/manual/R-ints.texi = rw-r--r-- -jre/languages/R/doc/manual/R-exts.R = rw-r--r-- -jre/languages/R/doc/manual/R-admin.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile.in = rw-r--r-- -jre/languages/R/doc/manual/R-lang.texi = rw-r--r-- -jre/languages/R/doc/manual/Makefile.win = rw-r--r-- -jre/languages/R/doc/manual/images/hist.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/hist.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig12.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig11.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/fig11.png = rw-r--r-- -jre/languages/R/doc/manual/images/fig12.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ecdf.png = rw-r--r-- -jre/languages/R/doc/manual/images/ice.png = rw-r--r-- -jre/languages/R/doc/manual/images/QQ.png = rw-r--r-- -jre/languages/R/doc/manual/images/QQ.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ecdf.pdf = rw-r--r-- -jre/languages/R/doc/manual/images/ice.pdf = rw-r--r-- -jre/languages/R/jline.jar = rw-r--r-- -jre/languages/R/antlr4.jar = rw-r--r-- -jre/languages/R/xz-1.8.jar = rw-r--r-- -jre/languages/R/fastr-launcher.jar = rw-r--r-- -jre/languages/R/bin/exec/R = rwxr-xr-x -jre/languages/R/bin/Rscript = rwxr-xr-x -jre/languages/R/3rd_party_licenses_fastr.txt = rw-r--r-- -jre/languages/R/native-image.properties = rw-r--r-- -jre/languages/R/README_FASTR = rw-r--r-- -jre/languages/R/LICENSE_FASTR = rw-r--r-- -LICENSE_FASTR = rwxrwxrwx -3rd_party_licenses_fastr.txt = rwxrwxrwx -bin/Rscript = rwxrwxrwx -bin/R = rwxrwxrwx -jre/languages/R/release = rw-rw-r-- -jre/bin/Rscript = rwxrwxrwx -jre/bin/R = rwxrwxrwx \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/symlinks deleted file mode 100644 index 0aeecbe46387..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/META-INF/symlinks +++ /dev/null @@ -1,3 +0,0 @@ -LICENSE_FASTR = jre/languages/R/LICENSE_FASTR -bin/R = ../jre/bin/R -jre/bin/R = ../languages/R/bin/R \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/LICENSE_FASTR b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/LICENSE_FASTR deleted file mode 100644 index 54975fbea0e8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/LICENSE_FASTR +++ /dev/null @@ -1,720 +0,0 @@ -Product License - GraalVM Community Edition 1.0 R Language Component - -This is a release of GraalVM Community Edition 1.0 R Language Component. This -particular copy of the software is released under version 3 of GNU General -Public License. - -Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved - -=========================================================================== - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. - -=========================================================================== - - WRITTEN OFFER FOR SOURCE CODE -For any software that you receive from Oracle in binary form which is licensed -under an open source license that gives you the right to receive the source -code for that binary, you can obtain a copy of the applicable source code by -visiting http://www.oracle.com/goto/opensourcecode. If the source code for the -binary was not provided to you with the binary, you can also receive a copy of -the source code on physical media by submitting a written request to the -address listed below or by sending an email to Oracle using the following link: - http://www.oracle.com/goto/opensourcecode/request. - -Oracle America, Inc. -Attn: Senior Vice President -Development and Engineering Legal -500 Oracle Parkway, 10th Floor -Redwood Shores, CA 94065 - -Your request should include: - • The name of the binary for which you are requesting the source code - • The name and version number of the Oracle product containing the binary - • The date you received the Oracle product - • Your name - • Your company name (if applicable) - • Your return mailing address and email, and - • A telephone number in the event we need to reach you. - -We may charge you a fee to cover the cost of physical media and processing. -Your request must be sent - a. within three (3) years of the date you received the Oracle product that -included the binary that is the subject of your request, or - b. in the case of code licensed under the GPL v3 for as long as Oracle -offers spare parts or customer support for that product model. - -=========================================================================== diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/README_FASTR b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/README_FASTR deleted file mode 100644 index a5283f739238..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/README_FASTR +++ /dev/null @@ -1,70 +0,0 @@ -[![Join the chat at https://gitter.im/graalvm/graal-core](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/graalvm/graal-core?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -A high-performance implementation of the R programming language, built on GraalVM. - -FastR aims to be: -* [efficient](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#4ab6): executing R language scripts faster than any other R runtime -* [polyglot](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#0f5c): allowing [polyglot interoperability](https://www.graalvm.org/docs/reference-manual/polyglot/) with other languages in the GraalVM ecosystem. -* [compatible](https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb#fff5): providing support for existing packages and the R native interface -* [embeddable](https://github.com/graalvm/examples/tree/master/r_java_embedding): allowing integration using the R embedding API or the GraalVM polyglot embedding SDK - - -The screenshot below shows Java application with embedded FastR engine. -The plot below was generated by `ggplot2` running on FastR and it shows -peak performance of the [raytracing example](http://www.tylermw.com/throwing-shade/). -The measurements were [reproduced independently](https://nextjournal.com/sdanisch/fastr-benchmark). - -![Java embedding](documentation/assets/javaui.png) -![Speedup](documentation/assets/speedup.png) - - ## Getting Started -See the documentation on the GraalVM website on how to [get GraalVM](https://www.graalvm.org/docs/getting-started/) and [install and use FastR](http://www.graalvm.org/docs/reference-manual/languages/r/). - -``` -$ $GRAALVM/bin/R -Type 'q()' to quit R. -> print("Hello R!") -[1] "Hello R!" -> -``` - -## Documentation - -The reference manual for FastR, which explains its advantages, its current limitations, compatibility and additional functionality is available on the [GraalVM website](http://www.graalvm.org/docs/reference-manual/languages/r/). - -Further documentation, including contributor/developer-oriented information, is in the [documentation folder](documentation/Index.md) of this repository. - -## Current Status - -The goal of FastR is to be a drop-in replacement for GNU-R, the reference implementation of the R language. -FastR faithfully implements the R language, and any difference in behavior is considered to be a bug. - -FastR is capable of running binary R packages built for GNU-R as long as those packages properly use the R extensions C API (for best results, it is recommended to install R packages from source). -FastR supports R graphics via the grid package and packages based on grid (like lattice and ggplot2). -We are currently working towards support for the base graphics package. -FastR currently supports many of the popular R packages, such as ggplot2, jsonlite, testthat, assertthat, knitr, Shiny, Rcpp, rJava, quantmod and more… - -Moreover, support for dplyr and data.table are on the way. -We are actively monitoring and improving FastR support for the most popular packages published on CRAN including all the tidyverse packages. -However, one should take into account the experimental state of FastR, there can be packages that are not compatible yet, and if you try it on a complex R application, it can stumble on those. - -## Stay connected with the community - -See [graalvm.org/community](https://www.graalvm.org/community/) on how to stay connected with the development community. -The discussion on [gitter](https://gitter.im/graalvm/graal-core) is a good way to get in touch with us. - -We would like to grow the FastR open-source community to provide a free R implementation atop the Truffle/Graal stack. -We encourage contributions, and invite interested developers to join in. -Prospective contributors need to sign the [Oracle Contributor Agreement (OCA)](http://www.oracle.com/technetwork/community/oca-486395.html). -The access point for contributions, issues and questions about FastR is the [GitHub repository](https://github.com/oracle/fastr). - -## Authors - -FastR is developed by Oracle Labs and is based on [the GNU-R runtime](http://www.r-project.org/). -It contains contributions by researchers at Purdue University ([purdue-fastr](https://github.com/allr/purdue-fastr)), Northeastern University, JKU Linz, TU Dortmund and TU Berlin. - -## License - -FastR is available under a GPLv3 license. - - diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/doc/THANKS b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/doc/THANKS deleted file mode 100644 index 6f8eb3ee226a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/doc/THANKS +++ /dev/null @@ -1,70 +0,0 @@ -R would not be what it is today without the invaluable help of these -people outside of the R core team, who contributed by donating code, bug -fixes and documentation: - -Valerio Aimale, Suharto Anggono, Thomas Baier, Henrik Bengtsson, Roger Bivand, -Ben Bolker, David Brahm, G"oran Brostr"om, Patrick Burns, Vince Carey, -Saikat DebRoy, Matt Dowle, Brian D'Urso, Lyndon Drake, Dirk Eddelbuettel, -Claus Ekstrom, Sebastian Fischmeister, John Fox, Paul Gilbert, -Yu Gong, Gabor Grothendieck, Frank E Harrell Jr, Peter M. Haverty, -Torsten Hothorn, Robert King, Kjetil Kjernsmo, Roger Koenker, Philippe Lambert, -Jan de Leeuw, Jim Lindsey, Patrick Lindsey, Catherine Loader, -Gordon Maclean, John Maindonald, David Meyer, Ei-ji Nakama, -Jens Oehlschaegel, Steve Oncley, Richard O'Keefe, Hubert Palme, -Roger D. Peng, Jose' C. Pinheiro, Tony Plate, Anthony Rossini, -Jonathan Rougier, Petr Savicky, Guenther Sawitzki, Marc Schwartz, -Arun Srinivasan, Detlef Steuer, Bill Simpson, Gordon Smyth, Adrian Trapletti, -Terry Therneau, Rolf Turner, Bill Venables, Gregory R. Warnes, -Andreas Weingessel, Morten Welinder, James Wettenhall, Simon Wood, and -Achim Zeileis. - -Others have written code that has been adopted by R and is -acknowledged in the code files, including - -J. D. Beasley, David J. Best, Richard Brent, Kevin Buhr, Michael -A. Covington, Bill Cleveland, Robert Cleveland,, G. W. Cran, -C. G. Ding, Ulrich Drepper, Paul Eggert, J. O. Evans, David M. Gay, -H. Frick, G. W. Hill, Richard H. Jones, Eric Grosse, Shelby Haberman, -Bruno Haible, John Hartigan, Andrew Harvey, Trevor Hastie, Min Long -Lam, George Marsaglia, K. J. Martin, Gordon Matzigkeit, -C. R. Mckenzie, Jean McRae, Cyrus Mehta, Fionn Murtagh, John C. Nash, -Finbarr O'Sullivan, R. E. Odeh, William Patefield, Nitin Patel, Alan -Richardson, D. E. Roberts, Patrick Royston, Russell Lenth, Ming-Jen -Shyu, Richard C. Singleton, S. G. Springer, Supoj Sutanthavibul, Irma -Terpenning, G. E. Thomas, Rob Tibshirani, Wai Wan Tsang, Berwin -Turlach, Gary V. Vaughan, Michael Wichura, Jingbo Wang, M. A. Wong, -and the Free Software Foundation (for autoconf code and utilities). -See also files under src/extras. - -Many more, too numerous to mention here, have contributed by sending bug -reports and suggesting various improvements. - -Simon Davies whilst at the University of Auckland wrote the original -version of glm(). - -Julian Harris and Wing Kwong (Tiki) Wan whilst at the University of -Auckland assisted Ross Ihaka with the original Macintosh port. - -R was inspired by the S environment which has been principally -developed by John Chambers, with substantial input from Douglas Bates, -Rick Becker, Bill Cleveland, Trevor Hastie, Daryl Pregibon and -Allan Wilks. - -A special debt is owed to John Chambers who has graciously contributed -advice and encouragement in the early days of R and later became a -member of the core team. - - - -The R Foundation may decide to give out @R-project.org -email addresses to contributors to the R Project (even without making them -members of the R Foundation) when in the view of the R Foundation this -would help advance the R project. - -The R Core Group, Roger Bivand, Jennifer Bryan, Di Cook, Dirk Eddelbuettel, -John Fox, Bettina Grün, Frank Harrell, Torsten Hothorn, Stefano Iacus, -Julie Josse, Balasubramanian Narasimhan, Marc Schwartz, Heather Turner, -Bill Venables, Hadley Wickham and Achim Zeileis are the ordinary members of -the R Foundation. -In addition, David Meyer and Simon Wood are also e-addressable by -.@R-project.org. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/include/linked b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/include/linked deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/library/utils/DESCRIPTION b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/library/utils/DESCRIPTION deleted file mode 100644 index e8a417ec3fe6..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/library/utils/DESCRIPTION +++ /dev/null @@ -1,11 +0,0 @@ -Package: utils -Version: 3.5.1 -Priority: base -Title: The R Utils Package -Author: R Core Team and contributors worldwide -Maintainer: R Core Team -Description: R utility functions. -License: Part of R 3.5.1 -Suggests: methods, xml2, commonmark -NeedsCompilation: yes -Built: R 3.5.1; x86_64-apple-darwin18.2.0; 2019-04-02 04:04:54 UTC; unix diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/native-image.properties deleted file mode 100644 index 0b896fe5ce53..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/native-image.properties +++ /dev/null @@ -1,28 +0,0 @@ -# This file contains native-image arguments needed to fastr -# - -ImageName = RMain - -Requires = tool:nfi \ - tool:chromeinspector \ - tool:nfi \ - tool:profiler - -JavaArgs = \ - -Dfastr.resource.factory.class=com.oracle.truffle.r.nodes.builtin.EagerResourceHandlerFactory \ - -Dfastr.internal.usemxbeans=false \ - -Dfastr.internal.usenativeeventloop=false \ - -Dfastr.internal.defaultdownloadmethod=wget \ - -Dfastr.internal.ignorejvmargs=true \ - -Dfastr.use.remote.grid.awt.device=true - -LauncherClass = com.oracle.truffle.r.launcher.RMain -LauncherClassPath = lib/graalvm/launcher-common.jar:languages/R/fastr-launcher.jar - -Args = --enable-http \ - -H:MaxRuntimeCompileMethods=8000 \ - -H:+UnlockExperimentalVMOptions \ - -H:-TruffleCheckFrameImplementation \ - -H:+TruffleCheckNeverPartOfCompilation \ - -H:-UseServiceLoaderFeature \ - -H:-UnlockExperimentalVMOptions diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/release deleted file mode 100644 index eb822705c23a..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=macos -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/share/java/README b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/share/java/README deleted file mode 100644 index 6201c0580eb8..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/r/1.1.0.0/jre/languages/R/share/java/README +++ /dev/null @@ -1,3 +0,0 @@ -getsp.class has source tools/getsp.java. - -It is installed for use by R CMD javareconf. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/MANIFEST.MF deleted file mode 100644 index 362a1f7feb04..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,13 +0,0 @@ -Bundle-Name: TruffleRuby -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Version: 1.0.1.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.0.1.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/ruby -x-GraalVM-Message-PostInst: \nIMPORTANT NOTE:\n---------------\nThe Ruby - openssl C extension needs to be recompiled on your system to work with - the installed libssl.\nFirst, make sure TruffleRuby's dependencies are i - nstalled, which are described at:\n https://github.com/oracle/truffleru - by/blob/master/README.md#dependencies\nThen run the following command:\n - ${graalvm_home}/jre/languages/ruby/lib/truffle/post_install_hook - .sh diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/permissions deleted file mode 100644 index bb398974f8a7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/permissions +++ /dev/null @@ -1,7 +0,0 @@ -bin/truffleruby = rwxrwxrwx -bin/rake = rwxrwxrwx -jre/bin/truffleruby = rwxrwxrwx -jre/bin/rake = rwxrwxrwx -LICENSE_TRUFFLERUBY.md = rwxrwxrwx -jre/languages/ruby/release = rw-rw-r-- -jre/languages/ruby/lib/cext/include/sulong/polyglot.h = rw-rw-r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/symlinks deleted file mode 100644 index fa711df113bd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/META-INF/symlinks +++ /dev/null @@ -1,6 +0,0 @@ -bin/ruby = ../jre/bin/ruby -bin/rake = ../jre/bin/rake -jre/bin/truffleruby = ../languages/ruby/bin/truffleruby -jre/bin/rake = ../languages/ruby/bin/rake -LICENSE_TRUFFLERUBY.md = jre/languages/ruby/LICENSE_TRUFFLERUBY.md -jre/languages/ruby/bin/ruby = truffleruby \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md deleted file mode 100644 index 8e3aea7e3802..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md +++ /dev/null @@ -1 +0,0 @@ -Some license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/README.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/README.md deleted file mode 100644 index e23317b39c52..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/README.md +++ /dev/null @@ -1,218 +0,0 @@ -![TruffleRuby logo](logo/png/truffleruby_logo_horizontal_medium.png) - -A high performance implementation of the Ruby programming language. Built on -[GraalVM](http://graalvm.org/) by [Oracle Labs](https://labs.oracle.com). - -## Getting started - -There are three ways to install TruffleRuby: - -* Via [GraalVM](doc/user/installing-graalvm.md), which includes support for - other languages such as JavaScript, R and Python and supports both the - [*native* and *JVM* configurations](#truffleruby-configurations). - Inside GraalVM will then be a `bin/ruby` command that runs TruffleRuby. - We recommend that you use a [Ruby manager](doc/user/ruby-managers.md#configuring-ruby-managers-for-the-full-graalvm-distribution) - to use TruffleRuby inside GraalVM. - -* Via your [Ruby manager/installer](doc/user/ruby-managers.md) (RVM, rbenv, - chruby, ruby-build, ruby-install). This contains only TruffleRuby, in the - [*native* configuration](#truffleruby-configurations), making it a smaller - download. It is meant for users just wanting a Ruby implementation and already - using a Ruby manager. - -* Using the [standalone distribution](doc/user/standalone-distribution.md) - as a simple binary tarball. This distribution is also useful for - [testing TruffleRuby in CI](doc/user/standalone-distribution.md). - On [TravisCI](https://docs.travis-ci.com/user/languages/ruby#truffleruby), you can simply use: - ```yaml - language: ruby - rvm: - - truffleruby - ``` - -You can use `gem` to install Gems as normal. - -You can also build TruffleRuby from source, see the -[building instructions](doc/contributor/workflow.md), and using -[Docker](doc/contributor/docker.md). - -Please report any issue you might find on [GitHub](https://github.com/oracle/truffleruby/issues). - -## Aim - -TruffleRuby aims to: - -* Run idiomatic Ruby code faster -* Run Ruby code in parallel -* Boot Ruby applications in less time -* Execute C extensions in a managed environment -* Add fast and low-overhead interoperability with languages like Java, JavaScript, Python and R -* Provide new tooling such as debuggers and monitoring -* All while maintaining very high compatibility with the standard implementation of Ruby - -## TruffleRuby configurations - -There are two main configurations of TruffleRuby: *native* and *JVM*. It's -important to understand the different configurations of TruffleRuby, as each has -different capabilities and performance characteristics. You should pick the -execution mode that is appropriate for your application. - -TruffleRuby by default runs in the *native* -configuration. In this configuration, TruffleRuby is ahead-of-time compiled to a -standalone native executable. This means that you don't need a JVM installed on -your system to use it. The advantage of the native configuration is that it -[starts about as fast as MRI](doc/contributor/svm.md), it may use less memory, -and it becomes fast in less time. The disadvantage of the native configuration -is that you can't use Java tools like VisualVM, you can't use Java -interoperability, and *peak performance may be lower than on the JVM*. The -native configuration is used by default, but you can also request it using -`--native`. To use polyglot programming with the *native* configuration, you -need to use the `--polyglot` flag. To check you are using the *native* -configuration, `ruby --version` should mention `Native`. - -TruffleRuby can also be used in the *JVM* configuration, where it runs as a -normal Java application on the JVM, as any other Java application would. The -advantage of the JVM configuration is that you can use Java interoperability, -and *peak performance may be higher than the native configuration*. The -disadvantage of the JVM configuration is that it takes much longer to start and -to get fast, and may use more memory. The JVM configuration is requested using -`--jvm`. To check you are using the *JVM* configuration, `ruby --version` should -not mention `Native`. - -If you are running a short-running program you probably want the default, -*native*, configuration. If you are running a long-running program and want the -highest possible performance you probably want the *JVM* configuration, by using -`--jvm`. - -At runtime you can tell if you are using the native configuration using -`TruffleRuby.native?`. - -You won't encounter it when using TruffleRuby from the GraalVM, but there is -also another configuration which is TruffleRuby running on the JVM but with the -Graal compiler not available. This configuration will have much lower -performance and should normally only be used for development. `ruby --version` -will mention `Interpreter` for this configuration. - -## System compatibility - -TruffleRuby is actively tested on these systems: - -* Oracle Linux 7 -* Ubuntu 18.04 LTS -* Ubuntu 16.04 LTS -* Fedora 28 -* macOS 10.14 (Mojave) -* macOS 10.13 (High Sierra) - -You may find that TruffleRuby will not work if you severely restrict the -environment, for example by unmounting system filesystems such as `/dev/shm`. - -## Dependencies - -* [LLVM](doc/user/installing-llvm.md) to build and run C extensions -* [libssl](doc/user/installing-libssl.md) for the `openssl` C extension -* [zlib](doc/user/installing-zlib.md) for the `zlib` C extension - -Without these dependencies, many libraries including RubyGems will not work. -TruffleRuby will try to print a nice error message if a dependency is missing, -but this can only be done on a best effort basis. - -You may also need to set up a [UTF-8 locale](doc/user/utf8-locale.md). - -## Current status - -We recommend that people trying TruffleRuby on their gems and applications -[get in touch with us](#contact) for help. - -TruffleRuby is progressing fast but is currently probably not ready for you to -try running your full Ruby application on. However it is ready for -experimentation and curious end-users to try on their gems and smaller -applications. - -TruffleRuby runs Rails, and passes the majority of the Rails test suite. But it -is missing support for Nokogiri and ActiveRecord database drivers which makes it -not practical to run real Rails applications at the moment. - -You will find that many C extensions will not work without modification. - -## Migration from MRI - -TruffleRuby should in most cases work as a drop-in replacement for MRI, but you -should read about our [compatibility](doc/user/compatibility.md). - -## Migration from JRuby - -For many use cases TruffleRuby should work as a drop-in replacement for JRuby. -However, our approach to integration with Java is different to JRuby so you -should read our [migration guide](doc/user/jruby-migration.md). - -## Documentation - -Extensive documentation is available in [`doc`](doc). -[`doc/user`](doc/user) documents how to use TruffleRuby and -[`doc/contributor`](doc/contributor) documents how to develop TruffleRuby. - -## Contact - -The best way to get in touch with us is to join us in -https://gitter.im/graalvm/truffleruby, but you can also Tweet to -[@TruffleRuby](https://twitter.com/truffleruby), or email -chris.seaton@oracle.com. - -## Mailing list - -Announcements about GraalVM, including TruffleRuby, are made on the -[graal-dev](http://mail.openjdk.java.net/mailman/listinfo/graal-dev) mailing list. - -## Authors - -The main authors of TruffleRuby in order of joining the project are: - -* Chris Seaton -* Benoit Daloze -* Kevin Menard -* Petr Chalupa -* Brandon Fish -* Duncan MacGregor -* Christian Wirth - -Additionally: - -* Thomas Würthinger -* Matthias Grimmer -* Josef Haider -* Fabio Niephaus -* Matthias Springer -* Lucas Allan Amorim -* Aditya Bhardwaj - -Collaborations with: - -* [Institut für Systemsoftware at Johannes Kepler University - Linz](http://ssw.jku.at) - -And others. - -## Security - -See the [security documentation](doc/user/security.md). - -## Licence - -TruffleRuby is copyright (c) 2013-2019 Oracle and/or its affiliates, and is made -available to you under the terms of any one of the following three licenses: - -* Eclipse Public License version 1.0, or -* GNU General Public License version 2, or -* GNU Lesser General Public License version 2.1. - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. - -## Attribution - -TruffleRuby is a fork of [JRuby](https://github.com/jruby/jruby), combining it -with code from the [Rubinius](https://github.com/rubinius/rubinius) project, and -also containing code from the standard implementation of Ruby, -[MRI](https://github.com/ruby/ruby). diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt deleted file mode 100644 index f06056fb45fb..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt +++ /dev/null @@ -1,56 +0,0 @@ -Ruby is copyrighted free software by Yukihiro Matsumoto . -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.0/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/MANIFEST.MF deleted file mode 100644 index f6716c2694e4..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/MANIFEST.MF +++ /dev/null @@ -1,13 +0,0 @@ -Bundle-Name: TruffleRuby -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Version: 1.0.1.1 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.0.1.1 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/ruby -x-GraalVM-Message-PostInst: \nIMPORTANT NOTE:\n---------------\nThe Ruby - openssl C extension needs to be recompiled on your system to work with - the installed libssl.\nFirst, make sure TruffleRuby's dependencies are i - nstalled, which are described at:\n https://github.com/oracle/truffleru - by/blob/master/README.md#dependencies\nThen run the following command:\n - ${graalvm_home}/jre/languages/ruby/lib/truffle/post_install_hook - .sh diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/permissions deleted file mode 100644 index bb398974f8a7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/permissions +++ /dev/null @@ -1,7 +0,0 @@ -bin/truffleruby = rwxrwxrwx -bin/rake = rwxrwxrwx -jre/bin/truffleruby = rwxrwxrwx -jre/bin/rake = rwxrwxrwx -LICENSE_TRUFFLERUBY.md = rwxrwxrwx -jre/languages/ruby/release = rw-rw-r-- -jre/languages/ruby/lib/cext/include/sulong/polyglot.h = rw-rw-r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/symlinks deleted file mode 100644 index fa711df113bd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/META-INF/symlinks +++ /dev/null @@ -1,6 +0,0 @@ -bin/ruby = ../jre/bin/ruby -bin/rake = ../jre/bin/rake -jre/bin/truffleruby = ../languages/ruby/bin/truffleruby -jre/bin/rake = ../languages/ruby/bin/rake -LICENSE_TRUFFLERUBY.md = jre/languages/ruby/LICENSE_TRUFFLERUBY.md -jre/languages/ruby/bin/ruby = truffleruby \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/LICENSE_TRUFFLERUBY.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/LICENSE_TRUFFLERUBY.md deleted file mode 100644 index 8e3aea7e3802..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/LICENSE_TRUFFLERUBY.md +++ /dev/null @@ -1 +0,0 @@ -Some license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/README.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/README.md deleted file mode 100644 index e23317b39c52..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/README.md +++ /dev/null @@ -1,218 +0,0 @@ -![TruffleRuby logo](logo/png/truffleruby_logo_horizontal_medium.png) - -A high performance implementation of the Ruby programming language. Built on -[GraalVM](http://graalvm.org/) by [Oracle Labs](https://labs.oracle.com). - -## Getting started - -There are three ways to install TruffleRuby: - -* Via [GraalVM](doc/user/installing-graalvm.md), which includes support for - other languages such as JavaScript, R and Python and supports both the - [*native* and *JVM* configurations](#truffleruby-configurations). - Inside GraalVM will then be a `bin/ruby` command that runs TruffleRuby. - We recommend that you use a [Ruby manager](doc/user/ruby-managers.md#configuring-ruby-managers-for-the-full-graalvm-distribution) - to use TruffleRuby inside GraalVM. - -* Via your [Ruby manager/installer](doc/user/ruby-managers.md) (RVM, rbenv, - chruby, ruby-build, ruby-install). This contains only TruffleRuby, in the - [*native* configuration](#truffleruby-configurations), making it a smaller - download. It is meant for users just wanting a Ruby implementation and already - using a Ruby manager. - -* Using the [standalone distribution](doc/user/standalone-distribution.md) - as a simple binary tarball. This distribution is also useful for - [testing TruffleRuby in CI](doc/user/standalone-distribution.md). - On [TravisCI](https://docs.travis-ci.com/user/languages/ruby#truffleruby), you can simply use: - ```yaml - language: ruby - rvm: - - truffleruby - ``` - -You can use `gem` to install Gems as normal. - -You can also build TruffleRuby from source, see the -[building instructions](doc/contributor/workflow.md), and using -[Docker](doc/contributor/docker.md). - -Please report any issue you might find on [GitHub](https://github.com/oracle/truffleruby/issues). - -## Aim - -TruffleRuby aims to: - -* Run idiomatic Ruby code faster -* Run Ruby code in parallel -* Boot Ruby applications in less time -* Execute C extensions in a managed environment -* Add fast and low-overhead interoperability with languages like Java, JavaScript, Python and R -* Provide new tooling such as debuggers and monitoring -* All while maintaining very high compatibility with the standard implementation of Ruby - -## TruffleRuby configurations - -There are two main configurations of TruffleRuby: *native* and *JVM*. It's -important to understand the different configurations of TruffleRuby, as each has -different capabilities and performance characteristics. You should pick the -execution mode that is appropriate for your application. - -TruffleRuby by default runs in the *native* -configuration. In this configuration, TruffleRuby is ahead-of-time compiled to a -standalone native executable. This means that you don't need a JVM installed on -your system to use it. The advantage of the native configuration is that it -[starts about as fast as MRI](doc/contributor/svm.md), it may use less memory, -and it becomes fast in less time. The disadvantage of the native configuration -is that you can't use Java tools like VisualVM, you can't use Java -interoperability, and *peak performance may be lower than on the JVM*. The -native configuration is used by default, but you can also request it using -`--native`. To use polyglot programming with the *native* configuration, you -need to use the `--polyglot` flag. To check you are using the *native* -configuration, `ruby --version` should mention `Native`. - -TruffleRuby can also be used in the *JVM* configuration, where it runs as a -normal Java application on the JVM, as any other Java application would. The -advantage of the JVM configuration is that you can use Java interoperability, -and *peak performance may be higher than the native configuration*. The -disadvantage of the JVM configuration is that it takes much longer to start and -to get fast, and may use more memory. The JVM configuration is requested using -`--jvm`. To check you are using the *JVM* configuration, `ruby --version` should -not mention `Native`. - -If you are running a short-running program you probably want the default, -*native*, configuration. If you are running a long-running program and want the -highest possible performance you probably want the *JVM* configuration, by using -`--jvm`. - -At runtime you can tell if you are using the native configuration using -`TruffleRuby.native?`. - -You won't encounter it when using TruffleRuby from the GraalVM, but there is -also another configuration which is TruffleRuby running on the JVM but with the -Graal compiler not available. This configuration will have much lower -performance and should normally only be used for development. `ruby --version` -will mention `Interpreter` for this configuration. - -## System compatibility - -TruffleRuby is actively tested on these systems: - -* Oracle Linux 7 -* Ubuntu 18.04 LTS -* Ubuntu 16.04 LTS -* Fedora 28 -* macOS 10.14 (Mojave) -* macOS 10.13 (High Sierra) - -You may find that TruffleRuby will not work if you severely restrict the -environment, for example by unmounting system filesystems such as `/dev/shm`. - -## Dependencies - -* [LLVM](doc/user/installing-llvm.md) to build and run C extensions -* [libssl](doc/user/installing-libssl.md) for the `openssl` C extension -* [zlib](doc/user/installing-zlib.md) for the `zlib` C extension - -Without these dependencies, many libraries including RubyGems will not work. -TruffleRuby will try to print a nice error message if a dependency is missing, -but this can only be done on a best effort basis. - -You may also need to set up a [UTF-8 locale](doc/user/utf8-locale.md). - -## Current status - -We recommend that people trying TruffleRuby on their gems and applications -[get in touch with us](#contact) for help. - -TruffleRuby is progressing fast but is currently probably not ready for you to -try running your full Ruby application on. However it is ready for -experimentation and curious end-users to try on their gems and smaller -applications. - -TruffleRuby runs Rails, and passes the majority of the Rails test suite. But it -is missing support for Nokogiri and ActiveRecord database drivers which makes it -not practical to run real Rails applications at the moment. - -You will find that many C extensions will not work without modification. - -## Migration from MRI - -TruffleRuby should in most cases work as a drop-in replacement for MRI, but you -should read about our [compatibility](doc/user/compatibility.md). - -## Migration from JRuby - -For many use cases TruffleRuby should work as a drop-in replacement for JRuby. -However, our approach to integration with Java is different to JRuby so you -should read our [migration guide](doc/user/jruby-migration.md). - -## Documentation - -Extensive documentation is available in [`doc`](doc). -[`doc/user`](doc/user) documents how to use TruffleRuby and -[`doc/contributor`](doc/contributor) documents how to develop TruffleRuby. - -## Contact - -The best way to get in touch with us is to join us in -https://gitter.im/graalvm/truffleruby, but you can also Tweet to -[@TruffleRuby](https://twitter.com/truffleruby), or email -chris.seaton@oracle.com. - -## Mailing list - -Announcements about GraalVM, including TruffleRuby, are made on the -[graal-dev](http://mail.openjdk.java.net/mailman/listinfo/graal-dev) mailing list. - -## Authors - -The main authors of TruffleRuby in order of joining the project are: - -* Chris Seaton -* Benoit Daloze -* Kevin Menard -* Petr Chalupa -* Brandon Fish -* Duncan MacGregor -* Christian Wirth - -Additionally: - -* Thomas Würthinger -* Matthias Grimmer -* Josef Haider -* Fabio Niephaus -* Matthias Springer -* Lucas Allan Amorim -* Aditya Bhardwaj - -Collaborations with: - -* [Institut für Systemsoftware at Johannes Kepler University - Linz](http://ssw.jku.at) - -And others. - -## Security - -See the [security documentation](doc/user/security.md). - -## Licence - -TruffleRuby is copyright (c) 2013-2019 Oracle and/or its affiliates, and is made -available to you under the terms of any one of the following three licenses: - -* Eclipse Public License version 1.0, or -* GNU General Public License version 2, or -* GNU Lesser General Public License version 2.1. - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. - -## Attribution - -TruffleRuby is a fork of [JRuby](https://github.com/jruby/jruby), combining it -with code from the [Rubinius](https://github.com/rubinius/rubinius) project, and -also containing code from the standard implementation of Ruby, -[MRI](https://github.com/ruby/ruby). diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/legal/ruby-licence.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/legal/ruby-licence.txt deleted file mode 100644 index f06056fb45fb..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/legal/ruby-licence.txt +++ /dev/null @@ -1,56 +0,0 @@ -Ruby is copyrighted free software by Yukihiro Matsumoto . -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.0.1.1/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/MANIFEST.MF deleted file mode 100644 index 44e6deadaa13..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,13 +0,0 @@ -Bundle-Name: TruffleRuby -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Version: 1.1.0.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.1.0.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/ruby -x-GraalVM-Message-PostInst: \nIMPORTANT NOTE:\n---------------\nThe Ruby - openssl C extension needs to be recompiled on your system to work with - the installed libssl.\nFirst, make sure TruffleRuby's dependencies are i - nstalled, which are described at:\n https://github.com/oracle/truffleru - by/blob/master/README.md#dependencies\nThen run the following command:\n - ${graalvm_home}/jre/languages/ruby/lib/truffle/post_install_hook - .sh diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/permissions deleted file mode 100644 index bb398974f8a7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/permissions +++ /dev/null @@ -1,7 +0,0 @@ -bin/truffleruby = rwxrwxrwx -bin/rake = rwxrwxrwx -jre/bin/truffleruby = rwxrwxrwx -jre/bin/rake = rwxrwxrwx -LICENSE_TRUFFLERUBY.md = rwxrwxrwx -jre/languages/ruby/release = rw-rw-r-- -jre/languages/ruby/lib/cext/include/sulong/polyglot.h = rw-rw-r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/symlinks deleted file mode 100644 index fa711df113bd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/META-INF/symlinks +++ /dev/null @@ -1,6 +0,0 @@ -bin/ruby = ../jre/bin/ruby -bin/rake = ../jre/bin/rake -jre/bin/truffleruby = ../languages/ruby/bin/truffleruby -jre/bin/rake = ../languages/ruby/bin/rake -LICENSE_TRUFFLERUBY.md = jre/languages/ruby/LICENSE_TRUFFLERUBY.md -jre/languages/ruby/bin/ruby = truffleruby \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md deleted file mode 100644 index 8e3aea7e3802..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md +++ /dev/null @@ -1 +0,0 @@ -Some license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/README.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/README.md deleted file mode 100644 index e23317b39c52..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/README.md +++ /dev/null @@ -1,218 +0,0 @@ -![TruffleRuby logo](logo/png/truffleruby_logo_horizontal_medium.png) - -A high performance implementation of the Ruby programming language. Built on -[GraalVM](http://graalvm.org/) by [Oracle Labs](https://labs.oracle.com). - -## Getting started - -There are three ways to install TruffleRuby: - -* Via [GraalVM](doc/user/installing-graalvm.md), which includes support for - other languages such as JavaScript, R and Python and supports both the - [*native* and *JVM* configurations](#truffleruby-configurations). - Inside GraalVM will then be a `bin/ruby` command that runs TruffleRuby. - We recommend that you use a [Ruby manager](doc/user/ruby-managers.md#configuring-ruby-managers-for-the-full-graalvm-distribution) - to use TruffleRuby inside GraalVM. - -* Via your [Ruby manager/installer](doc/user/ruby-managers.md) (RVM, rbenv, - chruby, ruby-build, ruby-install). This contains only TruffleRuby, in the - [*native* configuration](#truffleruby-configurations), making it a smaller - download. It is meant for users just wanting a Ruby implementation and already - using a Ruby manager. - -* Using the [standalone distribution](doc/user/standalone-distribution.md) - as a simple binary tarball. This distribution is also useful for - [testing TruffleRuby in CI](doc/user/standalone-distribution.md). - On [TravisCI](https://docs.travis-ci.com/user/languages/ruby#truffleruby), you can simply use: - ```yaml - language: ruby - rvm: - - truffleruby - ``` - -You can use `gem` to install Gems as normal. - -You can also build TruffleRuby from source, see the -[building instructions](doc/contributor/workflow.md), and using -[Docker](doc/contributor/docker.md). - -Please report any issue you might find on [GitHub](https://github.com/oracle/truffleruby/issues). - -## Aim - -TruffleRuby aims to: - -* Run idiomatic Ruby code faster -* Run Ruby code in parallel -* Boot Ruby applications in less time -* Execute C extensions in a managed environment -* Add fast and low-overhead interoperability with languages like Java, JavaScript, Python and R -* Provide new tooling such as debuggers and monitoring -* All while maintaining very high compatibility with the standard implementation of Ruby - -## TruffleRuby configurations - -There are two main configurations of TruffleRuby: *native* and *JVM*. It's -important to understand the different configurations of TruffleRuby, as each has -different capabilities and performance characteristics. You should pick the -execution mode that is appropriate for your application. - -TruffleRuby by default runs in the *native* -configuration. In this configuration, TruffleRuby is ahead-of-time compiled to a -standalone native executable. This means that you don't need a JVM installed on -your system to use it. The advantage of the native configuration is that it -[starts about as fast as MRI](doc/contributor/svm.md), it may use less memory, -and it becomes fast in less time. The disadvantage of the native configuration -is that you can't use Java tools like VisualVM, you can't use Java -interoperability, and *peak performance may be lower than on the JVM*. The -native configuration is used by default, but you can also request it using -`--native`. To use polyglot programming with the *native* configuration, you -need to use the `--polyglot` flag. To check you are using the *native* -configuration, `ruby --version` should mention `Native`. - -TruffleRuby can also be used in the *JVM* configuration, where it runs as a -normal Java application on the JVM, as any other Java application would. The -advantage of the JVM configuration is that you can use Java interoperability, -and *peak performance may be higher than the native configuration*. The -disadvantage of the JVM configuration is that it takes much longer to start and -to get fast, and may use more memory. The JVM configuration is requested using -`--jvm`. To check you are using the *JVM* configuration, `ruby --version` should -not mention `Native`. - -If you are running a short-running program you probably want the default, -*native*, configuration. If you are running a long-running program and want the -highest possible performance you probably want the *JVM* configuration, by using -`--jvm`. - -At runtime you can tell if you are using the native configuration using -`TruffleRuby.native?`. - -You won't encounter it when using TruffleRuby from the GraalVM, but there is -also another configuration which is TruffleRuby running on the JVM but with the -Graal compiler not available. This configuration will have much lower -performance and should normally only be used for development. `ruby --version` -will mention `Interpreter` for this configuration. - -## System compatibility - -TruffleRuby is actively tested on these systems: - -* Oracle Linux 7 -* Ubuntu 18.04 LTS -* Ubuntu 16.04 LTS -* Fedora 28 -* macOS 10.14 (Mojave) -* macOS 10.13 (High Sierra) - -You may find that TruffleRuby will not work if you severely restrict the -environment, for example by unmounting system filesystems such as `/dev/shm`. - -## Dependencies - -* [LLVM](doc/user/installing-llvm.md) to build and run C extensions -* [libssl](doc/user/installing-libssl.md) for the `openssl` C extension -* [zlib](doc/user/installing-zlib.md) for the `zlib` C extension - -Without these dependencies, many libraries including RubyGems will not work. -TruffleRuby will try to print a nice error message if a dependency is missing, -but this can only be done on a best effort basis. - -You may also need to set up a [UTF-8 locale](doc/user/utf8-locale.md). - -## Current status - -We recommend that people trying TruffleRuby on their gems and applications -[get in touch with us](#contact) for help. - -TruffleRuby is progressing fast but is currently probably not ready for you to -try running your full Ruby application on. However it is ready for -experimentation and curious end-users to try on their gems and smaller -applications. - -TruffleRuby runs Rails, and passes the majority of the Rails test suite. But it -is missing support for Nokogiri and ActiveRecord database drivers which makes it -not practical to run real Rails applications at the moment. - -You will find that many C extensions will not work without modification. - -## Migration from MRI - -TruffleRuby should in most cases work as a drop-in replacement for MRI, but you -should read about our [compatibility](doc/user/compatibility.md). - -## Migration from JRuby - -For many use cases TruffleRuby should work as a drop-in replacement for JRuby. -However, our approach to integration with Java is different to JRuby so you -should read our [migration guide](doc/user/jruby-migration.md). - -## Documentation - -Extensive documentation is available in [`doc`](doc). -[`doc/user`](doc/user) documents how to use TruffleRuby and -[`doc/contributor`](doc/contributor) documents how to develop TruffleRuby. - -## Contact - -The best way to get in touch with us is to join us in -https://gitter.im/graalvm/truffleruby, but you can also Tweet to -[@TruffleRuby](https://twitter.com/truffleruby), or email -chris.seaton@oracle.com. - -## Mailing list - -Announcements about GraalVM, including TruffleRuby, are made on the -[graal-dev](http://mail.openjdk.java.net/mailman/listinfo/graal-dev) mailing list. - -## Authors - -The main authors of TruffleRuby in order of joining the project are: - -* Chris Seaton -* Benoit Daloze -* Kevin Menard -* Petr Chalupa -* Brandon Fish -* Duncan MacGregor -* Christian Wirth - -Additionally: - -* Thomas Würthinger -* Matthias Grimmer -* Josef Haider -* Fabio Niephaus -* Matthias Springer -* Lucas Allan Amorim -* Aditya Bhardwaj - -Collaborations with: - -* [Institut für Systemsoftware at Johannes Kepler University - Linz](http://ssw.jku.at) - -And others. - -## Security - -See the [security documentation](doc/user/security.md). - -## Licence - -TruffleRuby is copyright (c) 2013-2019 Oracle and/or its affiliates, and is made -available to you under the terms of any one of the following three licenses: - -* Eclipse Public License version 1.0, or -* GNU General Public License version 2, or -* GNU Lesser General Public License version 2.1. - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. - -## Attribution - -TruffleRuby is a fork of [JRuby](https://github.com/jruby/jruby), combining it -with code from the [Rubinius](https://github.com/rubinius/rubinius) project, and -also containing code from the standard implementation of Ruby, -[MRI](https://github.com/ruby/ruby). diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt deleted file mode 100644 index f06056fb45fb..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt +++ /dev/null @@ -1,56 +0,0 @@ -Ruby is copyrighted free software by Yukihiro Matsumoto . -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0.0/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/MANIFEST.MF b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/MANIFEST.MF deleted file mode 100644 index 44e6deadaa13..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/MANIFEST.MF +++ /dev/null @@ -1,13 +0,0 @@ -Bundle-Name: TruffleRuby -Bundle-Symbolic-Name: org.graalvm.ruby -Bundle-Version: 1.1.0.0 -Bundle-RequireCapability: org.graalvm; filter:="(&(graalvm_version=1.1.0.0 - )(os_name=linux)(os_arch=amd64))" -x-GraalVM-Working-Directories: jre/languages/ruby -x-GraalVM-Message-PostInst: \nIMPORTANT NOTE:\n---------------\nThe Ruby - openssl C extension needs to be recompiled on your system to work with - the installed libssl.\nFirst, make sure TruffleRuby's dependencies are i - nstalled, which are described at:\n https://github.com/oracle/truffleru - by/blob/master/README.md#dependencies\nThen run the following command:\n - ${graalvm_home}/jre/languages/ruby/lib/truffle/post_install_hook - .sh diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/permissions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/permissions deleted file mode 100644 index bb398974f8a7..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/permissions +++ /dev/null @@ -1,7 +0,0 @@ -bin/truffleruby = rwxrwxrwx -bin/rake = rwxrwxrwx -jre/bin/truffleruby = rwxrwxrwx -jre/bin/rake = rwxrwxrwx -LICENSE_TRUFFLERUBY.md = rwxrwxrwx -jre/languages/ruby/release = rw-rw-r-- -jre/languages/ruby/lib/cext/include/sulong/polyglot.h = rw-rw-r-- \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/symlinks b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/symlinks deleted file mode 100644 index fa711df113bd..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/META-INF/symlinks +++ /dev/null @@ -1,6 +0,0 @@ -bin/ruby = ../jre/bin/ruby -bin/rake = ../jre/bin/rake -jre/bin/truffleruby = ../languages/ruby/bin/truffleruby -jre/bin/rake = ../languages/ruby/bin/rake -LICENSE_TRUFFLERUBY.md = jre/languages/ruby/LICENSE_TRUFFLERUBY.md -jre/languages/ruby/bin/ruby = truffleruby \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md deleted file mode 100644 index 8e3aea7e3802..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/LICENSE_TRUFFLERUBY.md +++ /dev/null @@ -1 +0,0 @@ -Some license diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/README.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/README.md deleted file mode 100644 index e23317b39c52..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/README.md +++ /dev/null @@ -1,218 +0,0 @@ -![TruffleRuby logo](logo/png/truffleruby_logo_horizontal_medium.png) - -A high performance implementation of the Ruby programming language. Built on -[GraalVM](http://graalvm.org/) by [Oracle Labs](https://labs.oracle.com). - -## Getting started - -There are three ways to install TruffleRuby: - -* Via [GraalVM](doc/user/installing-graalvm.md), which includes support for - other languages such as JavaScript, R and Python and supports both the - [*native* and *JVM* configurations](#truffleruby-configurations). - Inside GraalVM will then be a `bin/ruby` command that runs TruffleRuby. - We recommend that you use a [Ruby manager](doc/user/ruby-managers.md#configuring-ruby-managers-for-the-full-graalvm-distribution) - to use TruffleRuby inside GraalVM. - -* Via your [Ruby manager/installer](doc/user/ruby-managers.md) (RVM, rbenv, - chruby, ruby-build, ruby-install). This contains only TruffleRuby, in the - [*native* configuration](#truffleruby-configurations), making it a smaller - download. It is meant for users just wanting a Ruby implementation and already - using a Ruby manager. - -* Using the [standalone distribution](doc/user/standalone-distribution.md) - as a simple binary tarball. This distribution is also useful for - [testing TruffleRuby in CI](doc/user/standalone-distribution.md). - On [TravisCI](https://docs.travis-ci.com/user/languages/ruby#truffleruby), you can simply use: - ```yaml - language: ruby - rvm: - - truffleruby - ``` - -You can use `gem` to install Gems as normal. - -You can also build TruffleRuby from source, see the -[building instructions](doc/contributor/workflow.md), and using -[Docker](doc/contributor/docker.md). - -Please report any issue you might find on [GitHub](https://github.com/oracle/truffleruby/issues). - -## Aim - -TruffleRuby aims to: - -* Run idiomatic Ruby code faster -* Run Ruby code in parallel -* Boot Ruby applications in less time -* Execute C extensions in a managed environment -* Add fast and low-overhead interoperability with languages like Java, JavaScript, Python and R -* Provide new tooling such as debuggers and monitoring -* All while maintaining very high compatibility with the standard implementation of Ruby - -## TruffleRuby configurations - -There are two main configurations of TruffleRuby: *native* and *JVM*. It's -important to understand the different configurations of TruffleRuby, as each has -different capabilities and performance characteristics. You should pick the -execution mode that is appropriate for your application. - -TruffleRuby by default runs in the *native* -configuration. In this configuration, TruffleRuby is ahead-of-time compiled to a -standalone native executable. This means that you don't need a JVM installed on -your system to use it. The advantage of the native configuration is that it -[starts about as fast as MRI](doc/contributor/svm.md), it may use less memory, -and it becomes fast in less time. The disadvantage of the native configuration -is that you can't use Java tools like VisualVM, you can't use Java -interoperability, and *peak performance may be lower than on the JVM*. The -native configuration is used by default, but you can also request it using -`--native`. To use polyglot programming with the *native* configuration, you -need to use the `--polyglot` flag. To check you are using the *native* -configuration, `ruby --version` should mention `Native`. - -TruffleRuby can also be used in the *JVM* configuration, where it runs as a -normal Java application on the JVM, as any other Java application would. The -advantage of the JVM configuration is that you can use Java interoperability, -and *peak performance may be higher than the native configuration*. The -disadvantage of the JVM configuration is that it takes much longer to start and -to get fast, and may use more memory. The JVM configuration is requested using -`--jvm`. To check you are using the *JVM* configuration, `ruby --version` should -not mention `Native`. - -If you are running a short-running program you probably want the default, -*native*, configuration. If you are running a long-running program and want the -highest possible performance you probably want the *JVM* configuration, by using -`--jvm`. - -At runtime you can tell if you are using the native configuration using -`TruffleRuby.native?`. - -You won't encounter it when using TruffleRuby from the GraalVM, but there is -also another configuration which is TruffleRuby running on the JVM but with the -Graal compiler not available. This configuration will have much lower -performance and should normally only be used for development. `ruby --version` -will mention `Interpreter` for this configuration. - -## System compatibility - -TruffleRuby is actively tested on these systems: - -* Oracle Linux 7 -* Ubuntu 18.04 LTS -* Ubuntu 16.04 LTS -* Fedora 28 -* macOS 10.14 (Mojave) -* macOS 10.13 (High Sierra) - -You may find that TruffleRuby will not work if you severely restrict the -environment, for example by unmounting system filesystems such as `/dev/shm`. - -## Dependencies - -* [LLVM](doc/user/installing-llvm.md) to build and run C extensions -* [libssl](doc/user/installing-libssl.md) for the `openssl` C extension -* [zlib](doc/user/installing-zlib.md) for the `zlib` C extension - -Without these dependencies, many libraries including RubyGems will not work. -TruffleRuby will try to print a nice error message if a dependency is missing, -but this can only be done on a best effort basis. - -You may also need to set up a [UTF-8 locale](doc/user/utf8-locale.md). - -## Current status - -We recommend that people trying TruffleRuby on their gems and applications -[get in touch with us](#contact) for help. - -TruffleRuby is progressing fast but is currently probably not ready for you to -try running your full Ruby application on. However it is ready for -experimentation and curious end-users to try on their gems and smaller -applications. - -TruffleRuby runs Rails, and passes the majority of the Rails test suite. But it -is missing support for Nokogiri and ActiveRecord database drivers which makes it -not practical to run real Rails applications at the moment. - -You will find that many C extensions will not work without modification. - -## Migration from MRI - -TruffleRuby should in most cases work as a drop-in replacement for MRI, but you -should read about our [compatibility](doc/user/compatibility.md). - -## Migration from JRuby - -For many use cases TruffleRuby should work as a drop-in replacement for JRuby. -However, our approach to integration with Java is different to JRuby so you -should read our [migration guide](doc/user/jruby-migration.md). - -## Documentation - -Extensive documentation is available in [`doc`](doc). -[`doc/user`](doc/user) documents how to use TruffleRuby and -[`doc/contributor`](doc/contributor) documents how to develop TruffleRuby. - -## Contact - -The best way to get in touch with us is to join us in -https://gitter.im/graalvm/truffleruby, but you can also Tweet to -[@TruffleRuby](https://twitter.com/truffleruby), or email -chris.seaton@oracle.com. - -## Mailing list - -Announcements about GraalVM, including TruffleRuby, are made on the -[graal-dev](http://mail.openjdk.java.net/mailman/listinfo/graal-dev) mailing list. - -## Authors - -The main authors of TruffleRuby in order of joining the project are: - -* Chris Seaton -* Benoit Daloze -* Kevin Menard -* Petr Chalupa -* Brandon Fish -* Duncan MacGregor -* Christian Wirth - -Additionally: - -* Thomas Würthinger -* Matthias Grimmer -* Josef Haider -* Fabio Niephaus -* Matthias Springer -* Lucas Allan Amorim -* Aditya Bhardwaj - -Collaborations with: - -* [Institut für Systemsoftware at Johannes Kepler University - Linz](http://ssw.jku.at) - -And others. - -## Security - -See the [security documentation](doc/user/security.md). - -## Licence - -TruffleRuby is copyright (c) 2013-2019 Oracle and/or its affiliates, and is made -available to you under the terms of any one of the following three licenses: - -* Eclipse Public License version 1.0, or -* GNU General Public License version 2, or -* GNU Lesser General Public License version 2.1. - -TruffleRuby contains additional code not always covered by these licences, and -with copyright owned by other people. See -[doc/legal/legal.md](doc/legal/legal.md) for full documentation. - -## Attribution - -TruffleRuby is a fork of [JRuby](https://github.com/jruby/jruby), combining it -with code from the [Rubinius](https://github.com/rubinius/rubinius) project, and -also containing code from the standard implementation of Ruby, -[MRI](https://github.com/ruby/ruby). diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt deleted file mode 100644 index f06056fb45fb..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/legal/ruby-licence.txt +++ /dev/null @@ -1,56 +0,0 @@ -Ruby is copyrighted free software by Yukihiro Matsumoto . -You can redistribute it and/or modify it under either the terms of the -2-clause BSDL (see the file BSDL), or the conditions below: - - 1. You may make and give away verbatim copies of the source form of the - software without restriction, provided that you duplicate all of the - original copyright notices and associated disclaimers. - - 2. You may modify your copy of the software in any way, provided that - you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise - make them Freely Available, such as by posting said - modifications to Usenet or an equivalent medium, or by allowing - the author to include your modifications in the software. - - b) use the modified software only within your corporation or - organization. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 3. You may distribute the software in object code or binary form, - provided that you do at least ONE of the following: - - a) distribute the binaries and library files of the software, - together with instructions (in the manual page or equivalent) - on where to get the original distribution. - - b) accompany the distribution with the machine-readable source of - the software. - - c) give non-standard binaries non-standard names, with - instructions on where to get the original software distribution. - - d) make other distribution arrangements with the author. - - 4. You may modify and include the part of the software into any other - software (possibly commercial). But some files in the distribution - are not written by the author, so that they are not under these terms. - - For the list of those files and their copying conditions, see the - file LEGAL. - - 5. The scripts and library files supplied as input to or produced as - output from the software do not automatically fall under the - copyright of the software, but belong to whomever generated them, - and may be sold commercially, and may be aggregated with this - software. - - 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/user/netbeans.md b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/user/netbeans.md deleted file mode 100644 index 0e9236814854..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/doc/doc/user/netbeans.md +++ /dev/null @@ -1,29 +0,0 @@ -# NetBeans integration - -You can debug Ruby programs running in TruffleRuby using the NetBeans IDE. - -## Setup - -* Install NetBeans 8.2 -* Via Tools, Plugins, install 'Truffle Debugging Support' -* [Install TruffleRuby](installing-graalvm.md) - -We then need a project to debug. An example project that works well and -demonstrates features is available on GitHub: - -``` -$ git clone https://github.com/jtulach/sieve.git -``` - -Open `ruby+js/fromjava` as a NetBeans project. - -* Right click on the project -* Open Properties, Build, Compile, Java Platform -* Manage Java Platforms, Add Platform, and select the GraalVM directory -* Now we can set a breakpoint in Ruby by opening `sieve.rb` and clicking on the - line in `Natural#next` -* Finally, 'Debug Project' - -You will be able to debug the Ruby program as normal, and if you look at the -call stack you'll see that there are also Java and JavaScript frames that you -can debug as well, all inside the same virtual machine and debugger. diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/native-image.properties b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/native-image.properties deleted file mode 100644 index 69c2e64ac39f..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/native-image.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file contains native-image arguments needed to build truffleruby -# - -ImageName = truffleruby - -Requires = tool:truffle tool:nfi - -LauncherClass = org.truffleruby.launcher.RubyLauncher -LauncherClassPath = languages/ruby/truffleruby-annotations.jar:languages/ruby/truffleruby-shared.jar:lib/graalvm/launcher-common.jar:lib/graalvm/truffleruby-launcher.jar - -Args = -H:MaxRuntimeCompileMethods=5400 \ - -H:+AddAllCharsets - -JavaArgs = -Dpolyglot.image-build-time.PreinitializeContexts=ruby \ - -Dorg.graalvm.launcher.relative.llvm.home=../lib/cext/sulong-libs diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/release b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/release deleted file mode 100644 index dd1bb0bd9a4d..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/ruby/1.1.0_1.0/jre/languages/ruby/release +++ /dev/null @@ -1,3 +0,0 @@ -OS_NAME=linux -OS_ARCH=amd64 -GRAALVM_VERSION=1.0.0-rc15-dev diff --git a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/versions b/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/versions deleted file mode 100644 index 121a4f8613de..000000000000 --- a/vm/src/org.graalvm.component.installer.test/src/org/graalvm/component/installer/repo/versions +++ /dev/null @@ -1,12 +0,0 @@ -There are several versions: -1.0.0.0 with no update -1.0.1.0 with a patch 1.0.1.1 -1.1.0.0 with no update - -Python will be available in all releases. -Ruby is available in 1.0.0.0 and 1.0.1.0; patch exists for Ruby -R is available in 1.0.1.0 and 1.1.0.0; patch exists for R -No patch exists for Python - -Cores are available for 1.0.1.0 and 1.1.0.0 - diff --git a/vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/native-image.properties b/vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/native-image.properties deleted file mode 100644 index 148fc9626ed3..000000000000 --- a/vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/native-image.properties +++ /dev/null @@ -1,3 +0,0 @@ -Args = --enable-http --enable-https \ - --initialize-at-build-time=org.graalvm.component.installer \ - --initialize-at-run-time=sun.rmi,java.rmi diff --git a/vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/resource-config.json b/vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/resource-config.json deleted file mode 100644 index 97ce90a664a7..000000000000 --- a/vm/src/org.graalvm.component.installer/src/META-INF/native-image/org.graalvm/installer/resource-config.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "bundles": [ - { "name" : "org.graalvm.component.installer.Bundle" }, - { "name" : "org.graalvm.component.installer.commands.Bundle" }, - { "name" : "org.graalvm.component.installer.model.Bundle" }, - { "name" : "org.graalvm.component.installer.remote.Bundle" }, - { "name" : "org.graalvm.component.installer.os.Bundle" }, - { "name" : "org.graalvm.component.installer.persist.Bundle" }, - { "name" : "org.graalvm.component.installer.jar.Bundle" }, - { "name" : "org.graalvm.component.installer.ce.Bundle" }, - { "name" : "org.graalvm.component.installer.gds.Bundle" }, - { "name" : "org.graalvm.component.installer.gds.rest.Bundle" } - ] -} diff --git a/vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader b/vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader deleted file mode 100644 index 2b94a769fb65..000000000000 --- a/vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.ComponentArchiveReader +++ /dev/null @@ -1 +0,0 @@ -org.graalvm.component.installer.ce.JarPackageProvider diff --git a/vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory b/vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory deleted file mode 100644 index 6dd0b27cc30b..000000000000 --- a/vm/src/org.graalvm.component.installer/src/META-INF/services/org.graalvm.component.installer.SoftwareChannel$Factory +++ /dev/null @@ -1,3 +0,0 @@ -org.graalvm.component.installer.ce.WebCatalog$WebCatalogFactory -org.graalvm.component.installer.persist.DirectoryChannelFactory -org.graalvm.component.installer.gds.rest.GDSChannelFactory \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/AbstractIterable.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/AbstractIterable.java deleted file mode 100644 index 1d2a0c93ac7f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/AbstractIterable.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import org.graalvm.component.installer.ComponentCatalog.DownloadInterceptor; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.remote.RemoteComponentParam; - -/** - * Base class for the different commandline parameters. - * - * @author sdedic - */ -abstract class AbstractIterable implements ComponentIterable { - protected final CommandInput input; - protected final Feedback feedback; - private boolean verifyJars; - private CommandInput.CatalogFactory remoteFactory; - private ComponentCatalog remoteCatalog; - - protected AbstractIterable(CommandInput input, Feedback feedback) { - this.input = input; - this.feedback = feedback; - } - - public boolean isVerifyJars() { - return verifyJars; - } - - @Override - public void setVerifyJars(boolean verifyJars) { - this.verifyJars = verifyJars; - } - - public void setCatalogFactory(CommandInput.CatalogFactory cFactory) { - this.remoteFactory = cFactory; - } - - private ComponentCatalog getRemoteContents() { - if (remoteCatalog != null) { - return remoteCatalog; - } - if (remoteFactory != null) { - remoteCatalog = remoteFactory.createComponentCatalog(input); - } else { - remoteCatalog = new NullCatalog(); - } - return remoteCatalog; - } - - @Override - public ComponentIterable matchVersion(Version.Match m) { - return this; - } - - @Override - public ComponentIterable allowIncompatible() { - return this; - } - - @Override - public ComponentParam createParam(String cmdString, ComponentInfo info) { - RemoteComponentParam param = new CatalogIterable.CatalogItemParam( - getRemoteContents().getDownloadInterceptor(), - info, - info.getName(), - cmdString, - feedback, - input.optValue(Commands.OPTION_NO_DOWNLOAD_PROGRESS) == null); - param.setVerifyJars(verifyJars); - return param; - } - - private static class NullCatalog implements ComponentCatalog, DownloadInterceptor { - @Override - public boolean isAllowDistUpdate() { - return false; - } - - @Override - public ComponentInfo findComponentMatch(String id, Version.Match vmatch, boolean localOnly, boolean exact) { - return null; - } - - @Override - public Set findDependencies(ComponentInfo start, boolean closure, Boolean installed, Set result) { - return new HashSet<>(start.getDependencies()); - } - - @Override - public FileDownloader processDownloader(ComponentInfo info, FileDownloader dn) { - return dn; - } - - @Override - public DownloadInterceptor getDownloadInterceptor() { - return this; - } - - @Override - public void setAllowDistUpdate(boolean distUpgrade) { - } - - @Override - public ComponentInfo findComponentMatch(String id, Version.Match vm, boolean exact) { - return null; - } - - @Override - public String shortenComponentId(ComponentInfo info) { - return info.getId(); - } - - @Override - public Collection getComponentIDs() { - return Collections.emptyList(); - } - - @Override - public Collection loadComponents(String id, Version.Match selector, boolean filelist) { - return Collections.emptySet(); - } - - @Override - public boolean isRemoteEnabled() { - return false; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Archive.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Archive.java deleted file mode 100644 index bff195d1ed86..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Archive.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.channels.ReadableByteChannel; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * Simple abstraction over an archive, so that both JAR and RPMs (or other packaging) can be read. - * - * @author sdedic - */ -public interface Archive extends Iterable, AutoCloseable { - /** - * Opens an input stream for the entry. - * - * @param e file entry - * @return the input stream - * @throws IOException on I/O error - */ - InputStream getInputStream(FileEntry e) throws IOException; - - /** - * Checks that contents of the entry matches the given file. If the archive stores checksums, - * the method may not need do byte comparison but can only compute checksum/hash on the supplied - * content and compare to archive's info. - * - * @param bc the existing content - * @param entry archive entry - * @return true if the content is the same - * @throws IOException on I/O error - */ - boolean checkContentsMatches(ReadableByteChannel bc, FileEntry entry) throws IOException; - - /** - * Verifies integrity of the archive. - * - * @param input options for verificaion - * @return true, if the archive has been verified - * @throws IOException - */ - boolean verifyIntegrity(CommandInput input) throws IOException; - - /** - * Completes metadata in `info' with information within the archive's contents. This method may - * need to iterate through files in the archive. - * - * @param info - * @throws IOException - */ - void completeMetadata(ComponentInfo info) throws IOException; - - @Override - void close() throws IOException; - - /** - * Represents a single entry in the archive. - */ - interface FileEntry { - /** - * Returns name of the entry. Directory names should end with "/". - * - * @return entry name - */ - String getName(); - - /** - * @return true, if the entry represents a directory - */ - boolean isDirectory(); - - /** - * True, if the entry is a symbolic link. - * - * @return True, if the entry represents a symbolic link - */ - boolean isSymbolicLink(); - - /** - * Link target for symbolic links. - * - * @return target path - * @throws java.io.IOException if the link's target could not be read - * @throws IllegalStateException if the entry is not {@link #isSymbolicLink()}. - */ - String getLinkTarget() throws IOException; - - /** - * @return size of the content, only valid for regular files. - */ - long getSize(); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Bundle.properties deleted file mode 100644 index 79d99a97f960..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Bundle.properties +++ /dev/null @@ -1,139 +0,0 @@ -# To change this license header, choose License Headers in Project Properties. -# To change this template file, choose Tools | Templates -# and open the template in the editor. - -Installer_BuiltingCatalogURL=https://www.graalvm.org/component-catalog/graal-updater-component-catalog.properties - -INFO_InstallerVersion=GraalVM Component Updater v{0} -# {0} - additional options placeholder -INFO_Usage=\n\ - Usage: \n\ - \tgu info [-cClLnprstuvVJ] print info about a specific component (from a file, a URL or a catalog)\n\ - \tgu available [-aClvVJ] list components available in a catalog\n\ - \tgu install [-0CcDfiLMnosruvyxY] install a component package\n\ - \tgu list [-clvJ] list installed components, or components from a catalog\n\ - \tgu remove [-0DfMxv] uninstall a component\n\ - \tgu upgrade [-cCnLsuxSd] [] [] upgrade to a recent GraalVM or edition\n\ - \tgu rebuild-images rebuild native executables. Use -h for detailed usage\n\ -\n\ - Common options:\n\ - \ -A, --auto-yes respond YES or ACCEPT to all questions.\n\ - \ -c, --catalog treat parameters as component IDs from a catalog of GraalVM components. This is the default.\n\ - \ -C, --custom-catalog use user-supplied catalog at URL.\n\ - \ -e, --debug debugging. Prints stacktraces, ...\n\ - \ -E, --no-catalog-errors do not stop if at least one catalog is working.\n\ - \ -h, --help print help.\n\ - \ -L, --local-file, --file treat parameters as local filenames of packaged components.\n\ - \ -N, --non-interactive noninteractive mode. Fail when input is required.\n\ - \ --show-version print version information and continue.\n\ - \ -u, --url interpret parameters as URLs of packaged components.\n\ - \ -v, --verbose be verbose. Print versions and dependency information.\n\ - \ --version print version.\n\ -{0}\n\ - Use \n\ - \tgu -h\n\ - to get specific help. - -INFO_UsageExtensions=\n\ - Additonal options:\n\{0}\n - - -ERROR_MissingCommand=No command given. -ERROR_UnknownCommand=Unknown command: {0} -# {0} - option, including the leading - -# {1} - command -ERROR_UnsupportedOption=Command {1} does not support option -{0} -ERROR_CommandWithNoOptions=Command {1} does not support any options -ERROR_UnsupportedGlobalOption=Unknown option: -{0} -ERROR_OptionNeedsParameter=Missing required parameter for option {0} -ERROR_MissingCommand=Missing command. -ERROR_CannotFindPath=File not found: {0} -ERROR_InternalError=Internal error: {0} -ERROR_NoGraalVMDirectory=Could not find GraalVM installation directory. -ERROR_MissingParameter=Missing parameter for command {0} -ERROR_ReadingComponentRegistry=Error loading component registry. -ERROR_MissingFile=Missing file: {0} -ERROR_CorruptedRelease=Release file corrupted in GraalVM installation at: {0} -ERROR_ReleaseSourceRevisions=Could not parse source revisions in: {0} -ERROR_ReadingRealeaseFile=Error accessing release file {0}: {1} -ERROR_AmbiguousCommand=Command {0} is ambiguous. Could be {1} or {2} -ERROR_InvalidGraalVMDirectory=The GraalVM directory {0} is invalid. -ERROR_MultipleSourcesUnsupported=The updater cannot download from a catalog and from a specific URL at the same time. \ - Please run the updater separately for components from a catalog and components from custom URLs. -INSTALLER_Error=Error: {0} -# INSTALLER_InvalidCatalogURL=Catalog URL is invalid: {0} -# {0} - filename -ERROR_UnknownFileFormat=Unknown format: {0} -ERROR_MustBecomeUser=Insufficient privileges for administration of the GraalVM installation. \ - You need to become "{0}" user to perform administrative tasks on GraalVM. \n\ - NOTE: depending on your operating system, you may need to use OS tools to install or uninstall GraalVM components. -ERROR_MustBecomeAdmin=Insufficient privileges for administration of the GraalVM installation. \ - You need to operate as a system administrator to perform administrative tasks on GraalVM. \n\ - NOTE: depending on your operating system, you may need to use OS tools to install or uninstall GraalVM components. -ERROR_UnknownSystem=Operating system name '{0}' wasn't recognized. -STORAGE_CorruptedComponentStorage=Component metadata storage is corrupted. -STORAGE_InvalidReleaseFile=Invalid GraalVM release file. - - -INSTALLER_IOException=I/O error occurred: {0} -INSTALLER_FailError={0} -INSTALLER_FileDoesNotExist=File does not exist: {0} -INSTALLER_FileExists=File already exists: {0} -INSTALLER_DirectoryNotEmpty=Directory is not empty: {0} -INSTALLER_AccessDenied=Permission denied: {0} -INSTALLER_InvalidMetadata=Invalid component metadata or corrupted component package. -INSTALLER_InternalError=Internal error occurred: {0} - -REGISTRY_ReadingComponentList=Error reading component list: {0} -REGISTRY_ReadingComponentMetadata=Error reading metadata of component {0}: {1} - -INSTALL_Capability_graalvm_version=GraalVM Version -INSTALL_Capability_os_arch=Architecture -INSTALL_Capability_os_name=Operating System -INSTALL_Capability_os_variant=Operating System Variant -INSTALL_Capability_java_version=Java Version - - -VERIFY_VerboseCheckRequirements=Checking requirements of component {1} ({0}), version {2} -VERIFY_VerboseCapability=\tRequires {0} = {1}, GraalVM provides: {2} -VERIFY_VerboseCapabilityNone=None -VERIFY_ComponentExists=The same component {0} ({1}) is already installed in version {2} -VERIFY_Dependency_Failed=Component {0} could not be installed. It requires {1} {2}, but the GraalVM provides {3} -VERIFY_CapabilityMissing=None -VERIFY_UpdateGraalVM=Newer GraalVM is required for Component {0}, install GraalVM at least {1}. The current version is {2} -VERIFY_ObsoleteGraalVM=Component {0} requires older GraalVM {1}, the current version is {2}. Component cannot be installed. - -URL_InvalidDownloadURL=Invalid download URL {0}: {1} -URL_ErrorDownloadingNotExist=Component is not accessible at URL {0} -URL_ErrorDownloadingComponent=Error downloading component from {0}: {1} - -COMPONENT_Ambiguous=Component id {0} is ambiguous. Please use a qualified ID. -COMPONENT_AmbiguousIdFound=Component id {0} is ambiguous. It may match {0} or {1}. Please use a qualified ID. - -# {0} - error message -ERROR_RecordLicenseAccepted=WARNING: Could not write license acceptance: {0} -ERROR_UserInput=User input error: {0} -ERROR_Aborted=Terminated. -ERROR_SoftwareChannelBroken=Could not initialize software channel: {0} -ERROR_NoninteractiveInput=Installation in non-interactive mode required user input and was terminated. - -NAME_GraalCoreComponent=GraalVM Core - -VERSION_UnknownVersion1=Unknown version: {0} -VERSION_UnknownVersion2=Unknown version: {0}, try to refine build, e.g. {1} - -FILE_DeleteFailed=Delete of {0} failed: {1}. -FILE_ErrorRestoringPermissions=Error restoring permissions for {0}: {1} -FILE_CannotDeleteFileTryDelayed=Could not delete file or directory {0}, will try later: {1} -FILE_CannotInstallFileTryDelayed=Could not replace file {0}, will try later: {1} -FILE_CannotDeleteParentTryDelayed=Could not delete parent directory {0}, will try later. - -# {0} - installer version -# {1} - graalVM version -MSG_InstallerVersion=GraalVM Updater {0} -WARN_CouldNotCreateLog=Warning: Could not create log file {0}: {1}. Logging to stderr. -WARN_CouldNotInitializeLogManager=Warning: Could not initialize LogManager; using default logging settings. - -# {0} - error message from execution -ERR_InvokingJvmMode=Switch to JVM mode failed: {0} -ERROR_NoSha256Digest=SHA256 digest cannot be computed. Check your Java installation. diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/BundleConstants.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/BundleConstants.java deleted file mode 100644 index bc1cf0935759..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/BundleConstants.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Constants related to component packages / bundles and their structure. - */ -public class BundleConstants { - public static final String BUNDLE_ID = "Bundle-Symbolic-Name"; // NOI18N - public static final String BUNDLE_NAME = "Bundle-Name"; // NOI18N - public static final String BUNDLE_VERSION = "Bundle-Version"; // NOI18N - public static final String BUNDLE_REQUIRED = "Bundle-RequireCapability"; // NOI18N - public static final String BUNDLE_PROVIDED = "Bundle-ProvideCapability"; // NOI18N - public static final String BUNDLE_DEPENDENCY = "Require-Bundle"; // NOI18N - public static final String GRAALVM_CAPABILITY = "org.graalvm"; // NOI18N - public static final String BUNDLE_LICENSE_TYPE = "x-GraalVM-License-Type"; // NOI18N - public static final String BUNDLE_LICENSE_PATH = "x-GraalVM-License-Path"; // NOI18N - public static final String BUNDLE_STABILITY = "x-GraalVM-Stability"; // NOI18N - public static final String BUNDLE_STABILITY2 = "x-GraalVM-Stability-Level"; // NOI18N - - /** - * In manifests, can specify the serial/hashtag for a component. Used mainly in installed - * component storage, copied from download hash or ComponentInfo. - */ - public static final String BUNDLE_SERIAL = "x-GraalVM-Serial"; // NOI18N - - /** - * Extended optional attribute; marks directories, which should be removed completely without - * checking for emptiness. - */ - public static final String BUNDLE_WORKDIRS = "x-GraalVM-Working-Directories"; // NOI18N - - public static final String META_INF_PATH = "META-INF/"; // NOI18N - public static final String META_INF_PERMISSIONS_PATH = "META-INF/permissions"; // NOI18N - public static final String META_INF_SYMLINKS_PATH = "META-INF/symlinks"; // NOI18N - - public static final String GRAAL_COMPONENT_ID = GRAALVM_CAPABILITY; // NOI18N - - /** - * Post-install message. In the future more x-GraalVM-Message might appear - */ - public static final String BUNDLE_MESSAGE_POSTINST = "x-GraalVM-Message-PostInst"; // NOI18N - - /** - * Version key in the release file. - */ - public static final String GRAAL_VERSION = "graalvm_version"; // NOI18N - - /** - * Component distribution tag. Can be one of: - *
    - *
  • bundled - installed by a base package. Cannot be removed. - *
  • optional - installed as an add-on, can be removed. The default. - *
- * Further values may be added in the future. - * - * @since 20.0 - */ - public static final String BUNDLE_COMPONENT_DISTRIBUTION = "x-GraalVM-Component-Distribution"; // NOI18N - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommandInput.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommandInput.java deleted file mode 100644 index dc70cb9f5c7f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommandInput.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import org.graalvm.component.installer.model.ComponentRegistry; -import java.nio.file.Path; -import java.util.List; -import java.util.Map; -import org.graalvm.component.installer.model.GraalEdition; - -/** - * Provides access to command line parameters and useful variables. - */ -public interface CommandInput { - /** - * Iterates existingFiles on command line. - * - * @return next file from commandline - * @throws FailedOperationException if the named file does not exist. - */ - ComponentIterable existingFiles() throws FailedOperationException; - - /** - * Retrieves the next required parameter. - * - * @return parameter text - * @throws FailedOperationException if the parameter is missing. - */ - String requiredParameter() throws FailedOperationException; - - /** - * Returns the next parameter or {@code null} if all parameters were read. - * - * @return parametr text or {@code null} - */ - String nextParameter(); - - /** - * Peeks onto the next parameter. Does not consume it. A call to {@link #nextParameter} is - * required to advance. - */ - String peekParameter(); - - /** - * Has some parameters ? - */ - boolean hasParameter(); - - /** - * Path to the GraalVM installation. The value is already sanity-checked and represents a - * directory. - * - * @return Path to GraalVM installation. - */ - Path getGraalHomePath(); - - /** - * @return factory to create ComponentCatalogs - */ - CatalogFactory getCatalogFactory(); - - /** - * @return Registry of available components. - */ - ComponentCatalog getRegistry(); - - /** - * @return Registry of local components. - */ - ComponentRegistry getLocalRegistry(); - - /** - * Access to option parameters. Empty (non-{@code null} String} is returned for parameter-less - * options. - * - * @param option value of the option. - * @return option value; {@code null}, if the option is not present - */ - String optValue(String option); - - default String optValue(String option, String defV) { - String s = optValue(option); - return s == null ? defV : s; - } - - default boolean hasOption(String option) { - return optValue(option) != null; - } - - FileOperations getFileOperations(); - - /** - * Obtains a named parameter. - * - * @param key parameter name - * @param cmdLine true, if parameter is on cmdline (system properties); false if from - * environment (env vars) - * @return parameter value - */ - String getParameter(String key, boolean cmdLine); - - default String getParameter(String key, String defValue, boolean cmdLine) { - String s = getParameter(key, cmdLine); - return s != null ? s : defValue; - } - - /** - * Obtains a Map of named parameters. - * - * @param cmdLine - * @return parameters from commandline or environment - */ - Map parameters(boolean cmdLine); - - interface CatalogFactory { - /** - * Create a component catalog for the target VM installation, using the commandline options. - * - * @param input values for the catalog - * @return ComponentCatalog usable with target installation - */ - ComponentCatalog createComponentCatalog(CommandInput input); - - /** - * Lists GraalVM editions defined for the installation. - * - * @return graalvm editions. - */ - List listEditions(ComponentRegistry targetGraalVM); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Commands.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Commands.java deleted file mode 100644 index 11cc3bb75aed..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Commands.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Constants related to individual commands. Options, default values, ... - */ -public interface Commands { - /** - * Dry run - do not change anything on the disk. - */ - String OPTION_DRY_RUN = "0"; // NOI18N - String LONG_OPTION_DRY_RUN = "dry-run"; - - /** - * Replace existing components. - */ - String OPTION_REPLACE_COMPONENTS = "r"; // NOI18N - String LONG_OPTION_REPLACE_COMPONENTS = "replace"; // NOI18N - - /** - * Force - implies all replace + ignore options. - */ - String OPTION_FORCE = "f"; // NOI18N - String LONG_OPTION_FORCE = "force"; // NOI18N - - /** - * Interpret command line parameters as files. - */ - String OPTION_FILES = "L"; // NOI18N - String LONG_OPTION_FILES = "local-file"; // NOI18N - - @Deprecated String OPTION_FILES_OLD = "F"; // NOI18N - @Deprecated String LONG_OPTION_FILES_OLD = "file"; // NOI18N - - /** - * Replace different files. - */ - String OPTION_REPLACE_DIFFERENT_FILES = "o"; // NOI18N - String LONG_OPTION_REPLACE_DIFFERENT_FILES = "overwrite"; // NOI18N - - /** - * Do not terminate uninstall on failed file deletions. - */ - String OPTION_IGNORE_FAILURES = "x"; // NOI18N - String LONG_OPTION_IGNORE_FAILURES = "ignore"; // NOI18N - - /** - * List files. - */ - String OPTION_LIST_FILES = "l"; - String LONG_OPTION_LIST_FILES = "list-files"; - - /** - * Display full paths in lists. - */ - String OPTION_FULL_PATHS = "p"; - String LONG_OPTION_FULL_PATHS = "paths"; - - /** - * Ignore open errors, but report. - */ - String OPTION_IGNORE_OPEN_ERRORS = "r"; - String LONG_OPTION_IGNORE_OPEN_ERRORS = "ignore-open"; - - /** - * Hide download progress bar. - */ - String OPTION_NO_DOWNLOAD_PROGRESS = "n"; - String LONG_OPTION_NO_DOWNLOAD_PROGRESS = "no-progress"; - - /** - * Verifies JAR integrity. - */ - String OPTION_NO_VERIFY_JARS = "s"; - String LONG_OPTION_NO_VERIFY_JARS = "no-verify-jars"; - - /** - * Do not use tabular list. - */ - String OPTION_SUPPRESS_TABLE = "t"; - String LONG_OPTION_SUPPRESS_TABLE = "no-tables"; - - /** - * Verbose option, prints more messages. - */ - String OPTION_VERBOSE = "v"; // NOI18N - String LONG_OPTION_VERBOSE = "verbose"; // NOI18N - - /** - * Validate only. - */ - String OPTION_VALIDATE = "y"; - String LONG_OPTION_VALIDATE = "only-validate"; - - /** - * Full validation, may require download of components. - */ - String OPTION_VALIDATE_DOWNLOAD = "Y"; - String LONG_OPTION_VALIDATE_DOWNLOAD = "validate-before"; - - /** - * Print error stack traces. - */ - String OPTION_DEBUG = "e"; // NOI18N - String LONG_OPTION_DEBUG = "debug"; // NOI18N - - /** - * Help. - */ - String OPTION_HELP = "h"; - String LONG_OPTION_HELP = "help"; - - /** - * Interpret parameters as remote component IDs. - */ - String OPTION_CATALOG = "c"; - String LONG_OPTION_CATALOG = "catalog"; - - /** - * Interpret parameters as remote component IDs, uses user-defined catalog URL. - */ - String OPTION_FOREIGN_CATALOG = "C"; - String LONG_OPTION_FOREIGN_CATALOG = "custom-catalog"; - - /** - * Interpret parameters as URLs. - */ - String OPTION_URLS = "u"; - String LONG_OPTION_URLS = "url"; - - /** - * When present on a command, will terminate option processing and all parameters will be passed - * on as positionals. - */ - String DO_NOT_PROCESS_OPTIONS = "*"; - - /** - * Fails if a component which already exists is to be installed. - */ - String OPTION_FAIL_EXISTING = "i"; // NOI18N - String LONG_OPTION_FAIL_EXISTING = "fail-existing"; // NOI18N - - /** - * Automatic YES to all questions. - */ - String OPTION_AUTO_YES = "A"; - String LONG_OPTION_AUTO_YES = "auto-yes"; - - /** - * Abort on all prompts except YES/NO. - */ - String OPTION_NON_INTERACTIVE = "N"; - String LONG_OPTION_NON_INTERACTIVE = "non-interactive"; - - /** - * Return in JSON format if possible. - */ - String OPTION_JSON_OUTPUT = "J"; - String LONG_OPTION_JSON_OUTPUT = "json"; - - /** - * Operate on all components, irrespective of version. - */ - String OPTION_ALL = "a"; - String LONG_OPTION_ALL = "all-versions"; - - /** - * Ignores missing components on upgrade. - */ - String OPTION_IGNORE_MISSING_COMPONENTS = "x"; // NOI18N - String LONG_OPTION_IGNORE_MISSING_COMPONENTS = "ignore-missing"; // NOI18N - - String OPTION_VERSION = "V"; - String LONG_OPTION_VERSION = "use-version"; - - /** - * Uninstall other components depending on the uninstalled ones. - */ - String OPTION_UNINSTALL_DEPENDENT = "D"; - String LONG_OPTION_UNINSTALL_DEPENDENT = "remove-deps"; - - /** - * Attempt to resolve dependencies against local directories. - */ - String OPTION_LOCAL_DEPENDENCIES = "D"; - String LONG_OPTION_LOCAL_DEPENDENCIES = "local-deps"; - - /** - * Ignore component dependencies. - */ - String OPTION_NO_DEPENDENCIES = "M"; - String LONG_OPTION_NO_DEPENDENCIES = "no-deps"; - - /** - * Print version and exit. Non-alnum option to indicate the short form is not defined. - */ - String OPTION_PRINT_VERSION = "@"; - String LONG_OPTION_PRINT_VERSION = "version"; - - /** - * Show version and continue. Non-alnum option to indicate the short form is not defined. - */ - String OPTION_SHOW_VERSION = "#"; - String LONG_OPTION_SHOW_VERSION = "show-version"; - - /** - * Will not fail, if at least one of the catalogs can be read. - */ - String OPTION_IGNORE_CATALOG_ERRORS = "E"; - String LONG_OPTION_IGNORE_CATALOG_ERRORS = "no-catalog-errors"; - - /** - * Use specific edition. - */ - String OPTION_USE_EDITION = "$"; - String LONG_OPTION_USE_EDITION = "edition"; - - /** - * Show the core component. - */ - String OPTION_SHOW_CORE = "%"; - String LONG_OPTION_SHOW_CORE = "show-core"; - - /** - * Show updates to components. Implies --show-core. - */ - String OPTION_SHOW_UPDATES = "&"; - String LONG_OPTION_SHOW_UPDATES = "show-updates"; - - /** - * Install into target directory. - */ - String OPTION_TARGET_DIRECTORY = "d"; - String LONG_OPTION_TARGET_DIRECTORY = "target-dir"; - - /** - * Do not create or update symlink. - */ - String OPTION_NO_SYMLINK = "S"; - String LONG_OPTION_NO_SYMLINK = "no-symlink"; -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommonConstants.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommonConstants.java deleted file mode 100644 index f3d8badc4e33..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/CommonConstants.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Constants which do not fit elsewhere. - */ -public class CommonConstants { - /** - * The installer's version. Printed as part of the help message. - */ - public static final String INSTALLER_VERSION = "2.0.0"; // NOI18N - - public static final String CAP_GRAALVM_VERSION = "graalvm_version"; - public static final String CAP_OS_ARCH = "os_arch"; - public static final String CAP_OS_NAME = "os_name"; - public static final String CAP_OS_VARIANT = "os_variant"; - public static final String CAP_EDITION = "edition"; - public static final String CAP_JAVA_VERSION = "java_version"; - - public static final String EDITION_CE = "ce"; - - /** - * Replaceable token for the path to the graalvm installation. The token can be used in - * messages. - */ - public static final String TOKEN_GRAALVM_PATH = "graalvm_home"; // NOI18N - - /** - * Path to the runtime lib. Replaceable token for installation messages. - */ - public static final String TOKEN_GRAALVM_RTLIB_DIR = "graalvm_rtlib_dir"; // NOI18N - - /** - * Path to arch-dependent runtime lib. Replaceable token for installation messages. - */ - public static final String TOKEN_GRAALVM_RTLIB_ARCH_DIR = "graalvm_rtlib_arch_dir"; // NOI18N - - /** - * Path to languages home. Replaceable token for installation messages. - */ - public static final String TOKEN_GRAALVM_LANG_DIR = "graalvm_languages_dir"; // NOI18N - - /** - * Relative path for the component storage. - */ - public static final String PATH_COMPONENT_STORAGE = "lib/installer/components"; // NOI18N - - public static final String PATH_JRE_BIN = "bin/"; // NOI18N - - public static final String PATH_USER_GU = ".gu"; // NOI18N - - public static final String PATH_GDS_CONFIG = "config"; // NOI18N - - /** - * System property to specify catalog URL. - */ - public static final String SYSPROP_CATALOG_URL = "org.graalvm.component.catalog"; // NOI18N - - public static final String SYSPROP_JAVA_VERSION = "java.specification.version"; // NOI18N - - public static final String ENV_VARIABLE_PREFIX = "GRAALVM_"; // NOI18N - - /** - * Env variable that points to GraalVM home used for debug and development purposes. - */ - public static final String ENV_GRAALVM_HOME_DEV = "GRAALVM_HOME_DEV"; // NOI18N - - /** - * Env variable that controls catalog URL. - */ - public static final String ENV_CATALOG_URL = ENV_VARIABLE_PREFIX + "CATALOG"; // NOI18N - - /** - * Prefix for env variables that define catalog list. - */ - public static final String ENV_CATALOG_PREFIX = ENV_VARIABLE_PREFIX + "CATALOG_"; // NOI18N - /** - * Prefix for env variables that define catalog list. - */ - public static final String CAP_CATALOG_PREFIX = "component_catalog_"; // NOI18N - - public static final String CAP_CATALOG_EDITION = "edition"; // NOI18N - public static final String CAP_CATALOG_EDITION_NAME = "editionLabel"; // NOI18N - - public static final String CAP_CATALOG_URL = "url"; // NOI18N - public static final String CAP_CATALOG_LABEL = "label"; // NOI18N - - /** - * Component ID prefix for graalvm core components. The prefix will be stripped from the - * display, if the component is not ambiguous. - */ - public static final String GRAALVM_CORE_PREFIX = "org.graalvm"; // NOI18N - - /** - * Short ID of the GraalVM core component. - */ - public static final String GRAALVM_CORE_SHORT_ID = "graalvm"; // NOI18N - - /** - * Key in release file with catalog URL. - */ - public static final String RELEASE_CATALOG_KEY = "component_catalog"; // NOI18N - - /** - * Key in release file with GDS Product ID. - */ - public static final String RELEASE_GDS_PRODUCT_ID_KEY = "gds_product_id"; // NOI18N - - /** - * Default installation dir encoded in RPM packages. The installer will strip this prefix to - * relocate the package contents. - */ - public static final String BUILTIN_INSTALLATION_DIR = "/usr/lib/graalvm"; // NOI18N - - /** - * Origin of the component. A URL. Used only in directory-based registry of installed - * components. - */ - public static final String BUNDLE_ORIGIN_URL = "x-GraalVM-Component-Origin"; // NOI18N - - /** - * ID of the native-image component. - */ - public static final String NATIVE_IMAGE_ID = "native-image"; - - public static final String ENV_DELETE_LIST = "GU_POST_DELETE_LIST"; // NOI18N - public static final String ENV_COPY_CONTENTS = "GU_POST_COPY_CONTENTS"; // NOI18N - - public static final String ARCH_X8664 = "x86_64"; // NOI18N - public static final String ARCH_AARCH64 = "aarch64"; // NOI18N - public static final String ARCH_AMD64 = "amd64"; // NOI18N - - public static final String OS_MACOS_DARWIN = "darwin"; // NOI18N - public static final String OS_TOKEN_MAC = "mac"; // NOI18N - public static final String OS_TOKEN_MACOS = OS_TOKEN_MAC + "os"; // NOI18N - public static final String OS_TOKEN_LINUX = "linux"; // NOI18N - public static final String OS_TOKEN_WINDOWS = "windows"; // NOI18N - - /** - * Return code which will cause the wrapper to retry operations on locked files. - */ - public static final int WINDOWS_RETCODE_DELAYED_OPERATION = 11; - - /** - * Hacky way how to reach out to all classes. Used to switch the output to a script-readable - * format. - */ - public static final String SYSPROP_SIMPLE_OUTPUT = "org.graalvm.component.installer.SimpleOutput"; - - public static final String SYSPROP_OS_NAME = "os.name"; // NOI18N - public static final String SYSPROP_ARCH_NAME = "os.arch"; // NOI18N - public static final String SYSPROP_USER_HOME = "user.home"; // NOI18N - - public static final String JSON_KEY_COMPONENTS = "components"; // NOI18N - public static final String JSON_KEY_COMPONENT_ID = "id"; // NOI18N - public static final String JSON_KEY_COMPONENT_VERSION = "version"; // NOI18N - public static final String JSON_KEY_COMPONENT_NAME = "name"; // NOI18N - public static final String JSON_KEY_COMPONENT_FILENAME = "filename"; // NOI18N - public static final String JSON_KEY_COMPONENT_GRAALVM = "graalvm"; // NOI18N - public static final String JSON_KEY_COMPONENT_STABILITY = "stability"; // NOI18N - public static final String JSON_KEY_COMPONENT_ORIGIN = "origin"; // NOI18N - public static final String JSON_KEY_COMPONENT_FILES = "files"; // NOI18N - public static final String JSON_KEY_COMPONENT_REQUIRES = "requires"; // NOI18N - public static final String JSON_KEY_COMPONENT_ERRORS = "errors"; // NOI18N - public static final String JSON_KEY_COMPONENT_PROBLEMS = "problems"; // NOI18N - public static final String JSON_KEY_COMPONENT_LIC_IMPL_ACCEPT = "isLicenseImplicitlyAccepted"; // NOI18N -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentArchiveReader.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentArchiveReader.java deleted file mode 100644 index 0eeba51dd655..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentArchiveReader.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.nio.file.Path; -import org.graalvm.component.installer.persist.MetadataLoader; - -/** - * Recognizes file format and creates and loads metadata for it. - * - * @author sdedic - */ -public interface ComponentArchiveReader { - /** - * Creates a MetadataLoader for the file. The method returns {@code null}, if it does not - * support the file format. - * - * @param p path to the file - * @param fileStart bytes at the start of the file; min 8 bytes. - * @param feedback output interface - * @param verify verify archive integrity - * @param serial identification, optional. If not given the reader is likely to compute a digest - * on the archive, or the component metadata information - * @return Metadata loader instance or {@code null} if unsupported. - * @throws java.io.IOException if the loader creation or file open fails - */ - MetadataLoader createLoader(Path p, byte[] fileStart, String serial, Feedback feedback, boolean verify) throws IOException; -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCatalog.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCatalog.java deleted file mode 100644 index 356f6dd5c7ef..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCatalog.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.Set; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.remote.MergeStorage; - -/** - * - * @author sdedic - */ -public interface ComponentCatalog extends ComponentCollection { - ComponentInfo findComponentMatch(String id, Version.Match vmatch, boolean localOnly, boolean exact); - - /** - * Attempts to resolve dependencies or create dependency closure. The 'installed' parameter - * controls the search mode: - *
    - *
  • {@code true}: only search among installed components. Any unresolved dependencies are - * reported. - *
  • {@code false}: do not report components, which are already installed. - *
  • {@code null}: report both installed and uninstalled components. - *
- * - * @param installed controls handling for installed components. - * @param start the starting point - * @param closure if true, makes complete closure of dependencies. False inspects only 1st level - * dependencies. - * @param result set of dependencies. - * @return will contain ids whose Components could not be found. {@code null} is returned - * instead of empty collection for easier test. - */ - Set findDependencies(ComponentInfo start, boolean closure, Boolean installed, Set result); - - DownloadInterceptor getDownloadInterceptor(); - - /** - * @return True, if emote catalogs are enabled. - */ - boolean isRemoteEnabled(); - - interface DownloadInterceptor { - /** - * Configures the downloader, as appropriate for the catalog item. Note that the Catalog may - * reject configuration for a ComponentInfo it knows nothing about - will return - * {@code null} - * - * @param info component for which the Downloader should be configured - * @param dn the downloader instance - * @return the configured Downloader or {@code null}, if the ComponentInfo is not known. - */ - FileDownloader processDownloader(ComponentInfo info, FileDownloader dn); - - /** - * Allows to intercept metadata loader operations. The interface may be implemented on - * {@link SoftwareChannel} merged into {@link MergeStorage}. The default implementation - * simply returns the delegate itself. - * - * @param info component info for which the MetadataLoader is wanted - * @param delegate the original delegate - * @return possibly wrapped/delegated instance - */ - @SuppressWarnings("unused") - default MetadataLoader interceptMetadataLoader(ComponentInfo info, MetadataLoader delegate) { - return delegate; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCollection.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCollection.java deleted file mode 100644 index 2b0faa85270b..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentCollection.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.Collection; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * A facade that represents a component collection. - * - * @author sdedic - */ -public interface ComponentCollection { - default ComponentInfo findComponent(String id) { - return findComponent(id, null); - } - - boolean isAllowDistUpdate(); - - void setAllowDistUpdate(boolean distUpgrade); - - default ComponentInfo findComponent(String id, Version.Match vm) { - return findComponentMatch(id, vm, false); - } - - ComponentInfo findComponentMatch(String id, Version.Match vm, boolean exactId); - - String shortenComponentId(ComponentInfo info); - - Collection getComponentIDs(); - - Collection loadComponents(String id, Version.Match selector, boolean filelist); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentInstaller.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentInstaller.java deleted file mode 100644 index 83c4142126f5..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentInstaller.java +++ /dev/null @@ -1,929 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOError; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.AccessDeniedException; -import java.nio.file.DirectoryNotEmptyException; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.security.CodeSource; -import java.security.ProtectionDomain; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.function.Consumer; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogManager; -import java.util.logging.Logger; -import java.util.logging.SimpleFormatter; -import java.util.logging.StreamHandler; -import java.util.stream.Collectors; -import static org.graalvm.component.installer.CommonConstants.PATH_COMPONENT_STORAGE; -import org.graalvm.component.installer.commands.AvailableCommand; -import org.graalvm.component.installer.commands.InfoCommand; -import org.graalvm.component.installer.commands.InstallCommand; -import org.graalvm.component.installer.commands.ListInstalledCommand; -import org.graalvm.component.installer.commands.PostInstCommand; -import org.graalvm.component.installer.commands.PreRemoveCommand; -import org.graalvm.component.installer.commands.RebuildImageCommand; -import org.graalvm.component.installer.commands.UninstallCommand; -import org.graalvm.component.installer.commands.UpgradeCommand; -import org.graalvm.component.installer.gds.GdsCommands; -import org.graalvm.component.installer.gds.rest.GDSTokenStorage; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.os.WindowsJVMWrapper; -import org.graalvm.component.installer.persist.DirectoryStorage; -import org.graalvm.component.installer.remote.CatalogIterable; -import org.graalvm.component.installer.remote.GraalEditionList; -import org.graalvm.launcher.Launcher; -import org.graalvm.options.OptionCategory; -import org.graalvm.options.OptionDescriptor; - -/** - * The launcher. - */ -public class ComponentInstaller extends Launcher { - private static final Logger LOG = Logger.getLogger(ComponentInstaller.class.getName()); - - public static final String GRAAL_DEFAULT_RELATIVE_PATH = "../.."; // NOI18N - - private static final Environment SIMPLE_ENV = new Environment("help", Collections.emptyList(), Collections.emptyMap()).enableStacktraces(); // NOI18N - - private String command; - private InstallerCommand cmdHandler; - private LinkedList cmdlineParams; - private List parameters = Collections.emptyList(); - private Path graalHomePath; - private Path storagePath; - private SimpleGetopt options; - - static final Map commands = new HashMap<>(); - public static final Map globalOptions = new HashMap<>(); - public static final Map componentOptions = new HashMap<>(); - - @SuppressWarnings("deprecation") - static void initCommands() { - // not necessary except for tests to cleanup extra items - commands.clear(); - globalOptions.clear(); - - // options for commands working with component sources: - componentOptions.put(Commands.OPTION_CATALOG, ""); - componentOptions.put(Commands.OPTION_FILES, ""); - componentOptions.put(Commands.OPTION_URLS, ""); - componentOptions.put(Commands.OPTION_FOREIGN_CATALOG, "s"); - componentOptions.put(Commands.OPTION_FILES_OLD, "=L"); - - componentOptions.put(Commands.LONG_OPTION_FILES, Commands.OPTION_FILES); - componentOptions.put(Commands.LONG_OPTION_CATALOG, Commands.OPTION_CATALOG); - componentOptions.put(Commands.LONG_OPTION_URLS, Commands.OPTION_URLS); - componentOptions.put(Commands.LONG_OPTION_FOREIGN_CATALOG, Commands.OPTION_FOREIGN_CATALOG); - componentOptions.put(Commands.LONG_OPTION_FILES_OLD, Commands.OPTION_FILES); - - commands.put("install", new InstallCommand()); // NOI18N - commands.put("remove", new UninstallCommand()); // NOI18N - commands.put("list", new ListInstalledCommand()); // NOI18N - commands.put("available", new AvailableCommand()); // NOI18N - commands.put("info", new InfoCommand()); // NOI18N - commands.put("rebuild-images", new RebuildImageCommand()); // NOI18N - commands.put("update", new UpgradeCommand()); // NOI18N - commands.put("upgrade", new UpgradeCommand()); // NOI18N - - // commands used internally by system scripts, names intentionally hashed. - commands.put("#postinstall", new PostInstCommand()); // NOI18N - commands.put("#preremove", new PreRemoveCommand()); // NOI18N - - globalOptions.put(Commands.OPTION_VERBOSE, ""); - globalOptions.put(Commands.OPTION_DEBUG, ""); - globalOptions.put(Commands.OPTION_HELP, ""); - - globalOptions.put(Commands.LONG_OPTION_VERBOSE, Commands.OPTION_VERBOSE); - globalOptions.put(Commands.LONG_OPTION_DEBUG, Commands.OPTION_DEBUG); - globalOptions.put(Commands.LONG_OPTION_HELP, Commands.OPTION_HELP); - - globalOptions.put(Commands.OPTION_AUTO_YES, ""); - globalOptions.put(Commands.LONG_OPTION_AUTO_YES, Commands.OPTION_AUTO_YES); - - globalOptions.put(Commands.OPTION_NON_INTERACTIVE, ""); - globalOptions.put(Commands.LONG_OPTION_NON_INTERACTIVE, Commands.OPTION_NON_INTERACTIVE); - - globalOptions.put(Commands.OPTION_PRINT_VERSION, ""); - globalOptions.put(Commands.OPTION_SHOW_VERSION, ""); - - globalOptions.put(Commands.LONG_OPTION_PRINT_VERSION, Commands.OPTION_PRINT_VERSION); - globalOptions.put(Commands.LONG_OPTION_SHOW_VERSION, Commands.OPTION_SHOW_VERSION); - - globalOptions.put(Commands.OPTION_IGNORE_CATALOG_ERRORS, ""); - globalOptions.put(Commands.LONG_OPTION_IGNORE_CATALOG_ERRORS, Commands.OPTION_IGNORE_CATALOG_ERRORS); - - // for simplicity, these options are global, but still commands that use them should - // declare them explicitly. - globalOptions.putAll(componentOptions); - - } - - private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( - "org.graalvm.component.installer.Bundle"); // NOI18N - - public static void forSoftwareChannels(boolean report, Consumer callback) { - ServiceLoader channels = ServiceLoader.load(SoftwareChannel.Factory.class); - for (Iterator it = channels.iterator(); it.hasNext();) { - try { - SoftwareChannel.Factory ch = it.next(); - callback.accept(ch); - } catch (ServiceConfigurationError | Exception ex) { - if (report) { - LOG.log(Level.SEVERE, - MessageFormat.format(BUNDLE.getString("ERROR_SoftwareChannelBroken"), ex.getLocalizedMessage())); - } - } - } - } - - static { - initCommands(); - } - - public ComponentInstaller(String[] args) { - cmdlineParams = new LinkedList<>(Arrays.asList(args)); - } - - protected void printUsage(Feedback output) { - output.output("INFO_InstallerVersion", CommonConstants.INSTALLER_VERSION); // NOI18N - printHelp(output); - } - - private static void printHelp(Feedback output) { - StringBuilder extra = new StringBuilder(); - - forSoftwareChannels(true, (ch) -> { - ch.init(SIMPLE_ENV, output); - String s = ch.globalOptionsHelp(); - if (s != null && !s.isBlank()) { - extra.append(s).append("\n"); - } - }); - String extraS; - - if (extra.length() != 0) { - extraS = output.l10n("INFO_UsageExtensions", extra.substring(0, extra.length() - 1)); - } else { - extraS = ""; // NOI18N - } - - output.output("INFO_Usage", extraS); // NOI18N - } - - static void printErr(String messageKey, Object... args) { - SIMPLE_ENV.message(messageKey, args); - } - - static RuntimeException err(String messageKey, Object... args) { - printErr(messageKey, args); - printHelp(SIMPLE_ENV); - System.exit(1); - throw new RuntimeException("should not reach here"); - } - - protected RuntimeException error(String messageKey, Object... args) { - return err(messageKey, args); - } - - private Environment env; - private CommandInput input; - private Feedback feedback; - - CommandInput getInput() { - return input; - } - - protected void setInput(CommandInput input) { - this.input = input; - } - - Feedback getFeedback() { - return feedback; - } - - protected void setFeedback(Feedback feedback) { - this.feedback = feedback; - } - - Path getGraalHomePath() { - return graalHomePath; - } - - protected Environment setupEnvironment(SimpleGetopt go) { - Environment e = new Environment(command, parameters, go.getOptValues()); - setInput(e); - setFeedback(e); - return e; - } - - protected Environment completeEnvironment() { - if (env.getGraalHomePath() != null) { - return env; - } - - findGraalHome(); - env.setGraalHome(graalHomePath); - // Use our own GraalVM's trust store contents; also bypasses embedded trust store - // when running AOT. - Path trustStorePath = SystemUtils.resolveRelative(SystemUtils.getRuntimeBaseDir(env.getGraalHomePath()), - "lib/security/cacerts"); // NOI18N - System.setProperty("javax.net.ssl.trustStore", trustStorePath.normalize().toString()); // NOI18N - DirectoryStorage storage = new DirectoryStorage(env, storagePath, graalHomePath); - storage.setConfig(env); - storage.setJavaVersion("" + SystemUtils.getJavaMajorVersion(env)); - env.setLocalRegistry(new ComponentRegistry(env, storage)); - FileOperations fops = FileOperations.createPlatformInstance(env, env.getGraalHomePath()); - env.setFileOperations(fops); - - // also sets up input and feedback. - forSoftwareChannels(true, (ch) -> { - ch.init(input, feedback); - }); - - return env; - } - - protected SimpleGetopt createOptionsObject(Map opts) { - return new SimpleGetopt(opts); - } - - SimpleGetopt createOptions(LinkedList cmdline) { - SimpleGetopt go = createOptionsObject(globalOptions).ignoreUnknownOptions(true); - go.setParameters(new LinkedList<>(cmdline)); - for (String s : commands.keySet()) { - go.addCommandOptions(s, commands.get(s).supportedOptions()); - } - go.process(); - options = go; - command = go.getCommand(); - cmdHandler = commands.get(command); - parameters = go.getPositionalParameters(); - env = setupEnvironment(go); - return go; - } - - SimpleGetopt interpretOptions(SimpleGetopt go) { - completeEnvironment(); - List unknownOptions = go.getUnknownOptions(); - if (env.hasOption(Commands.OPTION_HELP) && go.getCommand() == null) { - unknownOptions.add("help"); - } - parseUnknownOptions(unknownOptions); - if (runLauncher()) { - return null; - } - return go; - } - - public String getCommand() { - return command; - } - - public List getParameters() { - return parameters; - } - - int processOptions(LinkedList cmdline) { - // setOutput(new EnvStream(true, new ByteArrayOutputStream(100))); - // setError(new EnvStream(true, new ByteArrayOutputStream(100))); - - if (cmdline.size() < 1) { - env = SIMPLE_ENV; - printDefaultHelp(OptionCategory.USER); - return 1; - } - - SimpleGetopt go = createOptions(cmdline); - launch(cmdline); - go = interpretOptions(go); - - if (go == null) { - return 0; - } - if (env.hasOption(Commands.OPTION_PRINT_VERSION)) { - printVersion(); - return 0; - } else if (env.hasOption(Commands.OPTION_SHOW_VERSION)) { - printVersion(); - } - if (env.hasOption(GdsCommands.OPTION_SHOW_TOKEN)) { - GDSTokenStorage.printToken(env, input); - return 0; - } - if (env.hasOption(GdsCommands.OPTION_REVOKE_TOKEN) || env.hasOption(GdsCommands.OPTION_REVOKE_CURRENT_TOKEN)) { - GDSTokenStorage.revokeToken(env, input, env.optValue(GdsCommands.OPTION_REVOKE_TOKEN)); - return 0; - } - if (env.hasOption(GdsCommands.OPTION_REVOKE_ALL_TOKENS)) { - GDSTokenStorage.revokeAllTokens(env, input, env.optValue(GdsCommands.OPTION_REVOKE_ALL_TOKENS)); - return 0; - } - - // check only after the version option: - if (cmdHandler == null) { - error("ERROR_MissingCommand"); // NOI18N - } - - int srcCount = 0; - if (input.hasOption(Commands.OPTION_FILES)) { - srcCount++; - } - if (input.hasOption(Commands.OPTION_URLS)) { - srcCount++; - } - if (srcCount > 1) { - error("ERROR_MultipleSourcesUnsupported"); - } - - if (input.hasOption(Commands.OPTION_AUTO_YES)) { - env.setAutoYesEnabled(true); - } - if (input.hasOption(Commands.OPTION_NON_INTERACTIVE)) { - env.setNonInteractive(true); - } - - // explicit location - String catalogURL = getExplicitCatalogURL(); - String builtinCatLocation = getReleaseCatalogURL(); - if (builtinCatLocation == null) { - builtinCatLocation = feedback.l10n("Installer_BuiltingCatalogURL"); - } - - GraalEditionList editionList = new GraalEditionList(feedback, input, input.getLocalRegistry()); - editionList.setDefaultCatalogSpec(builtinCatLocation); - editionList.setOverrideCatalogSpec(catalogURL); - env.setCatalogFactory(editionList); - - if (input.hasOption(Commands.OPTION_USE_EDITION)) { - input.getLocalRegistry().setOverrideEdition(input.optValue(Commands.OPTION_USE_EDITION)); - } - - boolean builtinsImplied = true; - boolean setIterable = true; - if (input.hasOption(Commands.OPTION_FILES)) { - FileIterable fi = new FileIterable(env, env); - fi.setCatalogFactory(editionList); - env.setFileIterable(fi); - - // optionally resolve local dependencies against parent directories - // of specified files. - builtinsImplied = false; - if (input.hasOption(Commands.OPTION_LOCAL_DEPENDENCIES)) { - while (env.hasParameter()) { - String s = env.nextParameter(); - Path p = SystemUtils.fromUserString(s); - if (p != null) { - Path parent = p.getParent(); - if (parent != null && Files.isDirectory(parent)) { - SoftwareChannelSource localSource = new SoftwareChannelSource(parent.toUri().toString(), null); - localSource.setPriority(10000); - editionList.addLocalChannelSource(localSource); - } - } - } - env.resetParameters(); - } - setIterable = false; - } else if (input.hasOption(Commands.OPTION_URLS)) { - DownloadURLIterable dit = new DownloadURLIterable(env, env); - dit.setCatalogFactory(editionList); - env.setFileIterable(dit); - setIterable = false; - builtinsImplied = false; - } - - if (setIterable) { - env.setFileIterable(new CatalogIterable(env, env)); - } - - editionList.setRemoteSourcesAllowed(builtinsImplied || env.hasOption(Commands.OPTION_CATALOG) || - env.hasOption(Commands.OPTION_FOREIGN_CATALOG)); - return -1; - } - - int doProcessCommand() throws IOException { - cmdHandler.init(input, feedback.withBundle(cmdHandler.getClass())); - return cmdHandler.execute(); - } - - private int processCommand(LinkedList cmds) { - int retcode = 0; - try { - retcode = processOptions(cmds); - if (retcode >= 0) { - return retcode; - } - // do not print before retcode check; parameters like --help may end the processing - // early, and - // INFO would be printed on default log level. - LOG.log(Level.INFO, "Installer starting"); - retcode = doProcessCommand(); - } catch (FileAlreadyExistsException ex) { - feedback.error("INSTALLER_FileExists", ex, ex.getLocalizedMessage()); // NOI18N - return 2; - } catch (NoSuchFileException ex) { - feedback.error("INSTALLER_FileDoesNotExist", ex, ex.getLocalizedMessage()); // NOI18N - return 2; - } catch (AccessDeniedException ex) { - feedback.error("INSTALLER_AccessDenied", ex, ex.getLocalizedMessage()); - return 2; - } catch (DirectoryNotEmptyException ex) { - feedback.error("INSTALLER_DirectoryNotEmpty", ex, ex.getLocalizedMessage()); // NOI18N - return 2; - } catch (IOError | IOException ex) { - feedback.error("INSTALLER_IOException", ex, ex.getLocalizedMessage()); // NOI18N - return 2; - } catch (MetadataException ex) { - feedback.error("INSTALLER_InvalidMetadata", ex, ex.getLocalizedMessage()); // NOI18N - return 3; - } catch (UserAbortException ex) { - feedback.error("ERROR_Aborted", ex, ex.getLocalizedMessage()); // NOI18N - return 4; - } catch (NonInteractiveException ex) { - return 5; - } catch (InstallerStopException ex) { - feedback.error("INSTALLER_Error", ex, ex.getLocalizedMessage()); // NOI18N - return 3; - } catch (AbortException ex) { - feedback.error(null, ex.getCause(), ex.getLocalizedMessage()); // NOI18N - return ex.getExitCode(); - } catch (RuntimeException ex) { - feedback.error("INSTALLER_InternalError", ex, ex.getLocalizedMessage()); // NOI18N - return 3; - } finally { - if (env != null) { - try { - if (env.close()) { - retcode = CommonConstants.WINDOWS_RETCODE_DELAYED_OPERATION; - } - } catch (IOException ex) { - } - } - } - return retcode; - } - - /** - * Finds Graal Home directory. It is either specified by the GRAALVM_HOME_DEV system property, - * environment variable, or the executing JAR's location - in the order of precedence. - *

- * The location is sanity checked and the method throws {@link FailedOperationException} if not - * proper Graal dir. - * - * @return existing Graal home - */ - Path findGraalHome() { - String graalHome = input.getParameter(CommonConstants.ENV_GRAALVM_HOME_DEV, // NOI18N - true); - Path graalPath = null; - if (graalHome != null) { - graalPath = SystemUtils.fromUserString(graalHome); - } else { - URL loc = null; - ProtectionDomain pd = ComponentInstaller.class.getProtectionDomain(); - if (pd != null) { - CodeSource cs = pd.getCodeSource(); - if (cs != null) { - loc = cs.getLocation(); - } - } - if (loc != null) { - try { - File f = new File(loc.toURI()); - Path guParent = f.isFile() ? f.toPath().getParent() : f.toPath(); - if (guParent != null) { - graalPath = guParent.resolve(SystemUtils.fromCommonString(GRAAL_DEFAULT_RELATIVE_PATH)).normalize().toAbsolutePath(); - Path p = graalPath.getFileName(); - if (p != null && "lib".equals(p.toString())) { // NOi18N - graalPath = graalPath.getParent(); - } - } - } catch (URISyntaxException ex) { - Logger.getLogger(ComponentInstaller.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - if (graalPath == null) { - throw SIMPLE_ENV.failure("ERROR_NoGraalVMDirectory", null); - } - if (!Files.isDirectory(graalPath) || !Files.exists(graalPath.resolve(SystemUtils.fileName("release")))) { - throw SIMPLE_ENV.failure("ERROR_InvalidGraalVMDirectory", null, graalPath); - } - if (!Files.isDirectory(storagePath = graalPath.resolve(SystemUtils.fromCommonString(PATH_COMPONENT_STORAGE)))) { - throw SIMPLE_ENV.failure("ERROR_InvalidGraalVMDirectory", null, graalPath); - } - graalHomePath = graalPath.normalize(); - - String libpath = System.getProperty("java.library.path"); // NOI18N - if (libpath == null || libpath.isEmpty()) { - // SVM mode: libpath is not define, define it to the JRE: - Path newLibPath = SystemUtils.getRuntimeLibDir(graalPath, true); - if (newLibPath == null) { - throw SIMPLE_ENV.failure("ERROR_UnknownSystem", null, System.getProperty("os.name")); // NOI18N - } - System.setProperty("java.library.path", newLibPath.toString()); // NOI18N - } - return graalPath; - } - - static void initGlobalOptions() { - forSoftwareChannels(true, (ch) -> { - ch.init(SIMPLE_ENV, SIMPLE_ENV); - globalOptions.putAll(ch.globalOptions()); - }); - } - - public void run() { - initGlobalOptions(); - try { - System.exit(processCommand(cmdlineParams)); - } catch (UserAbortException ex) { - SIMPLE_ENV.message("ERROR_Aborted", ex.getMessage()); // NOI18N - } catch (Exception ex) { - SIMPLE_ENV.error("ERROR_InternalError", ex, ex.getMessage()); // NOI18N - System.exit(3); - } - } - - String getExplicitCatalogURL() { - String def = null; - String cmdLine = input.optValue(Commands.OPTION_FOREIGN_CATALOG); - if (cmdLine != null) { - def = cmdLine; - } - String envVar = input.getParameter(CommonConstants.ENV_CATALOG_URL, false); - if (envVar != null) { - def = envVar; - } - String s = input.getParameter(CommonConstants.SYSPROP_CATALOG_URL, def, true); - if (s == null) { - return null; - } - boolean useAsFile = false; - - try { - URI check = URI.create(s); - if (check.getScheme() == null || check.getScheme().length() < 2) { - useAsFile = true; - } - } catch (IllegalArgumentException ex) { - // expected, use the argument as it is. - useAsFile = true; - } - if (useAsFile) { - Path p = SystemUtils.fromUserString(s); - // convert plain filename to file:// URL. - if (Files.isReadable(p) || Files.isDirectory(p)) { - return p.toFile().toURI().toString(); - } - } - return s; - } - - private String getReleaseCatalogURL() { - String s = env.getLocalRegistry().getGraalCapabilities().get(CommonConstants.RELEASE_CATALOG_KEY); - return s; - } - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - new ComponentInstaller(args).run(); - } - - /** - * Delegates the output to the {@link Environment} functions. The stream is configured into - * Launcher so that even SDK output goes through the single i/o point in GU. - */ - final class EnvStream extends PrintStream { - private final boolean error; - - EnvStream(boolean err, OutputStream dummyStream) { - super(dummyStream); - this.error = err; - } - - @Override - public PrintStream append(char c) { - env.verbatimPart("" + c, error); - return this; - } - - @Override - public PrintStream append(CharSequence csq, int start, int end) { - CharSequence cs = (csq == null ? "null" : csq); - append(cs.subSequence(start, end)); - return this; - } - - @Override - public PrintStream append(CharSequence csq) { - CharSequence cs = (csq == null ? "null" : csq); - env.verbatimPart(cs.toString(), error, false); - return this; - } - - @Override - public void println(Object x) { - println(String.valueOf(x)); - } - - @Override - public void println(String x) { - if (error) { - env.message(null, x); - } else { - env.output(null, x); - } - } - - @Override - public void println(char[] x) { - println(String.valueOf(x)); - } - - @Override - public void println(double x) { - println(String.valueOf(x)); - } - - @Override - public void println(float x) { - println(String.valueOf(x)); - } - - @Override - public void println(long x) { - println(String.valueOf(x)); - } - - @Override - public void println(int x) { - println(String.valueOf(x)); - } - - @Override - public void println(char x) { - println(String.valueOf(x)); - } - - @Override - public void println(boolean x) { - println(String.valueOf(x)); - } - - @Override - public void println() { - println(""); - } - - @Override - public void print(Object obj) { - print(String.valueOf(obj)); - } - - @Override - public void print(String s) { - env.verbatimPart(s, error, false); - } - - @Override - public void print(char[] s) { - print(String.valueOf(s)); - } - - @Override - public void print(double d) { - print(String.valueOf(d)); - } - - @Override - public void print(float f) { - print(String.valueOf(f)); - } - - @Override - public void print(long l) { - print(String.valueOf(l)); - } - - @Override - public void print(int i) { - print(String.valueOf(i)); - } - - @Override - public void print(char c) { - print(String.valueOf(c)); - } - - @Override - public void print(boolean b) { - print(String.valueOf(b)); - } - } - - /** - * Configures logging, based on `log.*' options passed on commandline. - * - * @param properties - */ - void configureLogging(Map properties) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(os); - Collection keep = new LinkedList<>(); - boolean rootLevelSet = false; - - for (String key : properties.keySet()) { - if (key.startsWith("log.") && key.endsWith(".level")) { // NOI18N - String v = properties.get(key); - if (v == null) { - continue; - } - String k; - - if (key.length() > 10) { - k = key.substring(4); - } else { - k = ".level"; // NOI18N - rootLevelSet = true; - } - ps.print(k); - ps.print('='); // NOI18N - ps.println(v); - keep.add(Logger.getLogger(k.substring(0, k.length() - 6))); - } - } - if (!rootLevelSet) { - // the default logging level, will prevent INFO messages to come out. - ps.println(".level=WARNING"); - } - // The default formatter is two -line; looks ugly. - ps.println("java.util.logging.SimpleFormatter.format=[%4$-7s] %5$s %n"); - ps.println(""); - try { - LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(os.toByteArray())); - } catch (IOException ex) { - env.error("WARN_CouldNotInitializeLogManager", ex, ex.getLocalizedMessage()); - return; - } - - Logger logger = Logger.getLogger(""); // NOI18N - - Handler[] old = logger.getHandlers(); - Path p = getLogFile(); - if (old.length > 0) { - // if there are existing handlers, should be sufficient to - // just set level on them. - for (int i = 0; i < old.length; i++) { - old[i].setLevel(Level.ALL); - } - } - if (old.length == 0 || p != null) { - OutputStream logOs = new EnvStream(true, System.err); - try { - if (p != null) { - logOs = newLogStream(getLogFile()); - } - } catch (IOException ex) { - env.error("WARN_CouldNotCreateLog", ex, p.toString(), ex.getLocalizedMessage()); - } - Handler h = new StreamHandler(logOs, new SimpleFormatter()); - h.setLevel(Level.ALL); - logger.addHandler(h); - } - } - - @Override - protected boolean canPolyglot() { - return false; - } - - public void launch(List args) { - maybeNativeExec(args, args, false); - // // Uncomment for debugging jvmmode launcher - // if (System.getProperty("test.wrap") != null) { - // maybeExec(args, args, false, VMType.Native); - // System.exit( - // executeJVMMode(System.getProperty("java.class.path"), args, args) // NOI18N - // ); - // } - } - - public Map parseUnknownOptions(List uOpts) { - List ooo = uOpts.stream().map((o) -> o.length() > 1 ? "--" + o : "-" + o).collect(Collectors.toList()); - Map polyOptions = new HashMap<>(); - parseUnrecognizedOptions(null, polyOptions, ooo); - - configureLogging(polyOptions); - - return polyOptions; - } - - @Override - protected void printHelp(OptionCategory maxCategory) { - printUsage(env); - } - - @Override - protected void printVersion() { - feedback.output("MSG_InstallerVersion", - env.getLocalRegistry().getGraalVersion().displayString()); - } - - public boolean runLauncher() { - return super.runLauncherAction(); - } - - @Override - protected void collectArguments(Set result) { - result.addAll(options.getAllOptions()); - } - - @Override - protected OptionDescriptor findOptionDescriptor(String group, String key) { - return null; - } - - /** - * Will act as a wrapper for an installer executing in JVM mode. NOTE: this method is only - * called in AOT mode. Unlike the default implementation, this will not replace the existing - * process, but rather execute a child process with env variables set up, then will perform the - * post-processing. - * - * @param jvmArgs JVM arguments for the process - * @param remainingArgs program arguments - */ - @Override - protected void executeJVM(String classpath, List jvmArgs, List remainingArgs) { - completeEnvironment(); - if (SystemUtils.isWindows()) { - int retcode = executeJVMMode(classpath, jvmArgs, remainingArgs); - System.exit(retcode); - } else { - super.executeJVM(classpath, jvmArgs, remainingArgs); - } - } - - int executeJVMMode(String classpath, List jvmArgs, List remainingArgs) { - WindowsJVMWrapper jvmWrapper = new WindowsJVMWrapper(env, - env.getFileOperations(), env.getGraalHomePath()); - jvmWrapper.vm(getGraalVMBinaryPath("java").toString(), jvmArgs).mainClass(getMainClass()).classpath(classpath).args(remainingArgs); - try { - return jvmWrapper.execute(); - } catch (IOException ex) { - throw env.failure("ERR_InvokingJvmMode", ex, ex.getMessage()); - } - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentIterable.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentIterable.java deleted file mode 100644 index ab657ef0ee32..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentIterable.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import org.graalvm.component.installer.model.ComponentInfo; - -public interface ComponentIterable extends Iterable { - void setVerifyJars(boolean verify); - - ComponentIterable matchVersion(Version.Match m); - - ComponentIterable allowIncompatible(); - - // XXX perhaps move to CatalogContents / ComponentCollection - ComponentParam createParam(String cmdString, ComponentInfo info); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentParam.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentParam.java deleted file mode 100644 index 13bbc3d5536d..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ComponentParam.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import org.graalvm.component.installer.persist.MetadataLoader; - -public interface ComponentParam { - String getSpecification(); - - String getDisplayName(); - - MetadataLoader createMetaLoader() throws IOException; - - MetadataLoader createFileLoader() throws IOException; - - boolean isComplete(); - - void close() throws IOException; - - String getFullPath(); - - String getShortName(); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Config.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Config.java deleted file mode 100644 index b8cc41910935..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Config.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Interface for GU environment object. Implemented by {@link Environment} and tests. - * - * @author sdedic - */ -public interface Config { - Config enableStacktraces(); - - boolean isAutoYesEnabled(); - - void setAutoYesEnabled(boolean autoYesEnabled); - - boolean isNonInteractive(); - - void setNonInteractive(boolean nonInteractive); - - void setAllOutputToErr(boolean allOutputToErr); - - void setFileIterable(ComponentIterable fileIterable); - - void setCatalogFactory(CommandInput.CatalogFactory catalogFactory); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DependencyException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DependencyException.java deleted file mode 100644 index c56d784153c6..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DependencyException.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Thrown on a failed requirement / dependency of a Component. - */ -public class DependencyException extends InstallerStopException { - private static final long serialVersionUID = 1L; - private final String component; - private final String version; - private final String installedVersion; - - /** - * Constructs a dependency exception. - * - * @param component component / feature which failed the requirement - * @param version version of the offending component/feature. {@code null} for conflicting - * component - * @param installedVersion the actually installed (offending) version. {@code null}, if the - * component is not installed and should be - * @param message display message - */ - public DependencyException(String component, String version, String installedVersion, String message) { - super(message); - this.component = component; - this.version = version; - this.installedVersion = installedVersion; - } - - public DependencyException(String component, String version, String message) { - super(message); - this.component = component; - this.version = version; - this.installedVersion = null; - } - - public String getComponent() { - return component; - } - - public String getVersion() { - return version; - } - - public String getInstalledVersion() { - return installedVersion; - } - - /** - * Represents a conflict between components. The same component is installed. - */ - public static class Conflict extends DependencyException { - private static final long serialVersionUID = 1L; - - public Conflict(String component, String version, String installedVersion, String message) { - super(component, version, installedVersion, message); - } - } - - /** - * Represents requirements mismatch. One component requires something, which is not satisfied by - * the installation (not present or wrong version) - */ - public static class Mismatch extends DependencyException { - private static final long serialVersionUID = 1L; - private final String capability; - - public Mismatch(String component, String capability, String version, String installedVersion, String message) { - super(component, version, installedVersion, message); - this.capability = capability; - } - - public String getCapability() { - return capability; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DownloadURLIterable.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DownloadURLIterable.java deleted file mode 100644 index 8f4b99d0daad..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/DownloadURLIterable.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import org.graalvm.component.installer.remote.RemoteComponentParam; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Path; -import java.util.Iterator; -import org.graalvm.component.installer.FileIterable.FileComponent; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.MetadataLoader; - -public class DownloadURLIterable extends AbstractIterable { - - public DownloadURLIterable(Feedback feedback, CommandInput input) { - super(input, feedback); - } - - @Override - public Iterator iterator() { - return new It(); - } - - @Override - public ComponentIterable matchVersion(Version.Match m) { - return this; - } - - @Override - public ComponentIterable allowIncompatible() { - return this; - } - - class It implements Iterator { - - @Override - public boolean hasNext() { - return input.hasParameter(); - } - - @Override - public ComponentParam next() { - String s = input.nextParameter(); - URL u; - try { - u = SystemUtils.toURL(s); - } catch (MalformedURLException ex) { - throw feedback.failure("URL_InvalidDownloadURL", ex, s, ex.getLocalizedMessage()); - } - boolean progress = input.optValue(Commands.OPTION_NO_DOWNLOAD_PROGRESS) == null; - RemoteComponentParam p = new DownloadURLParam(u, s, s, feedback, progress); - p.setVerifyJars(isVerifyJars()); - return p; - } - } - - static class DownloadURLParam extends RemoteComponentParam { - - DownloadURLParam(URL remoteURL, String dispName, String spec, Feedback feedback, boolean progress) { - super(remoteURL, dispName, spec, feedback, progress); - } - - @Override - protected MetadataLoader metadataFromLocal(Path localFile) throws IOException { - FileComponent fc = new FileComponent(localFile.toFile(), isVerifyJars(), - SystemUtils.fingerPrint(getDownloader().getReceivedDigest(), false), getFeedback()); - return fc.createFileLoader(); - } - - @Override - public ComponentInfo completeMetadata() throws IOException { - return createFileLoader().completeMetadata(); - } - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Environment.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Environment.java deleted file mode 100644 index 249d0f6828f9..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Environment.java +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.Console; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import org.graalvm.component.installer.model.ComponentRegistry; -import java.io.PrintStream; -import java.net.URL; -import java.nio.file.Path; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.function.Supplier; - -/** - * Implementation of feedback and input for commands. - */ -@SuppressWarnings("this-escape") -public class Environment implements Feedback, CommandInput, Config { - private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( - "org.graalvm.component.installer.Bundle"); - - private final String commandName; - private final LinkedList parameters; - private final Map options; - private final boolean verbose; - private final ResourceBundle bundle; - private int parameterPos; - private InputStream in = System.in; - private PrintStream err = System.err; - private PrintStream out = System.out; - private ComponentRegistry localRegistry; - private boolean stacktraces; - private ComponentIterable fileIterable; - private final Map fileMap = new HashMap<>(); - private final Map>> responseHeadersMap = new HashMap<>(); - private boolean allOutputToErr; - private boolean autoYesEnabled; - private boolean nonInteractive; - private boolean silent; - private Path graalHome; - private FileOperations fileOperations; - private CatalogFactory catalogFactory; - private ComponentCatalog componentCatalog; - - Environment(String commandName, List parameters, Map options) { - this(commandName, (String) null, parameters, options); - } - - Environment(String commandName, InstallerCommand cmdInstance, List parameters, Map options) { - this(commandName, makeBundle(cmdInstance), parameters, options); - } - - public void setIn(InputStream input) { - this.in = input; - } - - private static String makeBundle(InstallerCommand cmdInstance) { - if (cmdInstance == null) { - return null; - } - String s = cmdInstance.getClass().getName(); - s = s.substring(0, s.lastIndexOf('.')); - return s; - } - - public Environment(String commandName, String bundlePackage, List parameters, Map options) { - this.commandName = commandName; - this.parameters = new LinkedList<>(parameters); - this.options = options; - this.verbose = options.containsKey(Commands.OPTION_VERBOSE); - this.stacktraces = options.containsKey(Commands.OPTION_DEBUG); - if (bundlePackage != null) { - bundle = ResourceBundle.getBundle(bundlePackage + ".Bundle"); // NOI18N - } else { - bundle = BUNDLE; - } - - this.fileIterable = new FileIterable(this, this); - } - - @Override - public Environment enableStacktraces() { - this.stacktraces = true; - return this; - } - - @Override - public boolean isAutoYesEnabled() { - return autoYesEnabled; - } - - @Override - public void setAutoYesEnabled(boolean autoYesEnabled) { - this.autoYesEnabled = autoYesEnabled; - } - - @Override - public boolean isNonInteractive() { - return nonInteractive; - } - - @Override - public void setNonInteractive(boolean nonInteractive) { - this.nonInteractive = nonInteractive; - } - - public boolean isAllOutputToErr() { - return allOutputToErr; - } - - @Override - public void setAllOutputToErr(boolean allOutputToErr) { - this.allOutputToErr = allOutputToErr; - if (allOutputToErr) { - out = err; - } else { - out = System.out; - } - } - - @Override - public void setFileIterable(ComponentIterable fileIterable) { - this.fileIterable = fileIterable; - } - - @Override - public void setCatalogFactory(CatalogFactory catalogFactory) { - this.catalogFactory = catalogFactory; - } - - @Override - public ComponentCatalog getRegistry() { - if (componentCatalog == null) { - componentCatalog = catalogFactory.createComponentCatalog(this); - } - return componentCatalog; - } - - @Override - public ComponentRegistry getLocalRegistry() { - return localRegistry; - } - - public void setLocalRegistry(ComponentRegistry r) { - this.localRegistry = r; - } - - public void setGraalHome(Path f) { - this.graalHome = f.normalize(); - - } - - public void setErr(PrintStream err) { - this.err = err; - } - - public void setOut(PrintStream out) { - this.out = out; - } - - @Override - public void error(String bundleKey, Throwable error, Object... args) { - error(bundleKey, bundle, error, args); - } - - private void error(String bundleKey, ResourceBundle srcBundle, Throwable error, Object... args) { - boolean wasSilent = setSilent(false); - print(false, srcBundle, err, bundleKey, args); - if (stacktraces && error != null) { - error.printStackTrace(err); - } - setSilent(wasSilent); - } - - /** - * Wraps the error into a {@link FailedOperationException}. - * - * @param bundleKey - * @param error - * @param args - * @return exception which can be thrown - */ - @Override - public RuntimeException failure(String bundleKey, Throwable error, Object... args) { - return new FailedOperationException(createMessage(bundle, bundleKey, args), error); - } - - @Override - public void message(String bundleKey, Object... args) { - print(false, bundle, err, bundleKey, args); - } - - @Override - public boolean verbosePart(String bundleKey, Object... args) { - if (bundleKey != null) { - print(true, false, bundle, out, bundleKey, args); - } - return verbose; - } - - @Override - public void output(String bundleKey, Object... args) { - print(false, bundle, out, bundleKey, args); - } - - @Override - public void outputPart(String bundleKey, Object... args) { - print(false, false, bundle, out, bundleKey, args); - } - - @Override - public boolean verboseOutput(String bundleKey, Object... args) { - if (bundleKey != null) { - print(true, bundle, out, bundleKey, args); - } - return verbose; - } - - @Override - public String l10n(String bundleKey, Object... args) { - return createMessage(bundle, bundleKey, args); - } - - @Override - public boolean verbatimOut(String msg, boolean beVerbose) { - print(beVerbose, true, null, out, msg); - return beVerbose; - } - - @Override - public boolean verbatimPart(String msg, boolean beVerbose) { - print(beVerbose, false, null, out, msg); - return beVerbose; - } - - @Override - public boolean verbatimPart(String msg, boolean error, boolean beVerbose) { - print(beVerbose, false, null, error ? err : out, msg); - return beVerbose; - } - - @Override - public boolean backspace(int chars, boolean beVerbose) { - if (beVerbose && !verbose) { - return false; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < chars; i++) { - sb.append('\b'); - } - verbatimPart(sb.toString(), beVerbose); - return verbose; - } - - @Override - public Feedback withBundle(Class clazz) { - String s = clazz.getName(); - s = s.substring(0, s.lastIndexOf('.')); - ResourceBundle localBundle = ResourceBundle.getBundle(s + ".Bundle"); // NOI18N - - return new Feedback() { - @Override - public void message(String bundleKey, Object... params) { - print(false, localBundle, err, bundleKey, params); - } - - @Override - public void output(String bundleKey, Object... params) { - print(false, localBundle, out, bundleKey, params); - } - - @Override - public boolean verbosePart(String bundleKey, Object... params) { - if (bundleKey != null) { - print(true, false, localBundle, out, bundleKey, params); - } - return verbose; - } - - @Override - public boolean verboseOutput(String bundleKey, Object... params) { - if (bundleKey != null) { - print(true, localBundle, out, bundleKey, params); - } - return verbose; - } - - @Override - public boolean verbatimOut(String msg, boolean verboseOutput) { - print(verboseOutput, null, out, msg); - return verboseOutput; - } - - @Override - public void error(String key, Throwable t, Object... params) { - Environment.this.error(key, localBundle, t, params); - } - - @Override - public String l10n(String key, Object... params) { - return createMessage(localBundle, key, params); - } - - @Override - public RuntimeException failure(String key, Throwable t, Object... params) { - return new FailedOperationException(createMessage(localBundle, key, params), t); - } - - @Override - public Feedback withBundle(Class anotherClazz) { - return Environment.this.withBundle(anotherClazz); - } - - @Override - public void outputPart(String bundleKey, Object... params) { - print(false, false, localBundle, out, bundleKey, params); - } - - @Override - public boolean verbatimPart(String msg, boolean verboseOutput) { - print(verboseOutput, false, null, out, msg); - return verbose; - } - - @Override - public boolean verbatimPart(String msg, boolean error, boolean verboseOutput) { - print(verboseOutput, false, null, error ? err : out, msg); - return verbose; - } - - @Override - public boolean backspace(int chars, boolean beVerbose) { - return Environment.this.backspace(chars, beVerbose); - } - - @Override - public String acceptLine(boolean autoYes) { - return Environment.this.acceptLine(autoYes); - } - - @Override - public char[] acceptPassword() { - return Environment.this.acceptPassword(); - } - - @Override - public void addLocalFileCache(URL location, Path local) { - Environment.this.addLocalFileCache(location, local); - } - - @Override - public Path getLocalCache(URL location) { - return Environment.this.getLocalCache(location); - } - - @Override - public boolean isNonInteractive() { - return Environment.this.isNonInteractive(); - } - - @Override - public boolean isSilent() { - return Environment.this.isSilent(); - } - - @Override - public boolean setSilent(boolean silent) { - return Environment.this.setSilent(silent); - } - - @Override - public void addLocalResponseHeadersCache(URL location, Map> local) { - Environment.this.addLocalResponseHeadersCache(location, local); - } - - @Override - public Map> getLocalResponseHeadersCache(URL location) { - return Environment.this.getLocalResponseHeadersCache(location); - } - }; - } - - @SuppressWarnings({"unchecked"}) - private static String createMessage(ResourceBundle bundle, String bundleKey, Object... args) { - if (bundle == null) { - return bundleKey; - } - if (args == null) { - return bundle.getString(bundleKey); - } - for (int i = 0; i < args.length; i++) { - Object o = args[i]; - if (o instanceof Supplier) { - Object v = ((Supplier) o).get(); - if (v == null || v instanceof String) { - args[i] = v; - } - } - } - if (bundleKey == null) { - return String.valueOf(args[0]); - } - return MessageFormat.format( - bundle.getString(bundleKey), - args); - } - - private void print(boolean beVerbose, ResourceBundle msgBundle, PrintStream stm, String bundleKey, Object... args) { - if (beVerbose && !this.verbose) { - return; - } - print(beVerbose, true, msgBundle, stm, bundleKey, args); - } - - private void print(boolean beVerbose, boolean addNewline, ResourceBundle msgBundle, PrintStream stm, String bundleKey, Object... args) { - if (silent || (beVerbose && !this.verbose)) { - return; - } - if (addNewline) { - stm.println(createMessage(msgBundle, bundleKey, args)); - stm.flush(); - } else { - stm.print(createMessage(msgBundle, bundleKey, args)); - stm.flush(); - } - } - - @Override - public Path getGraalHomePath() { - return graalHome; - } - - @Override - public String nextParameter() { - if (parameterPos >= parameters.size()) { - return null; - } - return parameters.get(parameterPos++); - } - - @Override - public String peekParameter() { - if (parameterPos >= parameters.size()) { - return null; - } - return parameters.get(parameterPos); - } - - @Override - public String requiredParameter() { - if (!hasParameter()) { - throw new FailedOperationException( - MessageFormat.format(BUNDLE.getString("ERROR_MissingParameter"), commandName)); - } - return nextParameter(); - } - - @Override - public boolean hasParameter() { - return parameters.size() > parameterPos; - } - - @Override - public ComponentIterable existingFiles() { - return fileIterable; - } - - @Override - public String optValue(String optName) { - return options.get(optName); - } - - public char acceptCharacter() { - try { - int input = in.read(); - if (input == -1) { - throw new UserAbortException(); - } - return (char) input; - } catch (EOFException ex) { - throw new UserAbortException(ex); - } catch (IOException ex) { - throw withBundle(Environment.class).failure("ERROR_UserInput", ex, ex.getMessage()); - } - } - - @Override - public String acceptLine(boolean autoYes) { - if (autoYes && isAutoYesEnabled()) { - return AUTO_YES; - } - if (isNonInteractive()) { - throw new NonInteractiveException(withBundle(Environment.class).l10n("ERROR_NoninteractiveInput")); - } - StringBuilder sb = new StringBuilder(); - char c; - while ((c = acceptCharacter()) != '\n') { - if (c == 0x08) { - sb.delete(sb.length() - 1, sb.length()); - } else { - sb.append(c); - } - } - if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '\r') { - sb.delete(sb.length() - 1, sb.length()); - } - return sb.toString(); - } - - @Override - public char[] acceptPassword() { - if (isNonInteractive()) { - throw new NonInteractiveException(withBundle(Environment.class).l10n("ERROR_NoninteractiveInput")); - } - Console console = System.console(); - if (console != null) { - console.flush(); - return console.readPassword(); - } else { - return acceptLine(false).toCharArray(); - } - } - - @Override - public void addLocalFileCache(URL location, Path local) { - fileMap.put(location, local); - } - - @Override - public Path getLocalCache(URL location) { - return fileMap.get(location); - } - - @Override - public void addLocalResponseHeadersCache(URL location, Map> local) { - responseHeadersMap.put(location, local); - } - - @Override - public Map> getLocalResponseHeadersCache(URL location) { - return responseHeadersMap.get(location); - } - - @Override - public FileOperations getFileOperations() { - return fileOperations; - } - - public void setFileOperations(FileOperations fileOperations) { - this.fileOperations = fileOperations; - } - - public boolean close() throws IOException { - if (out != null) { - out.flush(); - } - if (err != null) { - err.flush(); - } - if (fileOperations != null) { - return fileOperations.flush(); - } else { - return false; - } - } - - @Override - public CatalogFactory getCatalogFactory() { - return catalogFactory; - } - - public void resetParameters() { - parameterPos = 0; - } - - @Override - public String getParameter(String key, boolean cmdLine) { - if (cmdLine) { - return System.getProperty(key); - } else { - return System.getenv(key.toUpperCase(Locale.ENGLISH)); - } - } - - @Override - public Map parameters(boolean cmdLine) { - if (cmdLine) { - Map res = new HashMap<>(); - for (String s : System.getProperties().stringPropertyNames()) { - res.put(s, System.getProperty(s)); - } - return res; - } else { - return System.getenv(); - } - } - - @Override - public boolean isSilent() { - return silent; - } - - @Override - public boolean setSilent(boolean silent) { - boolean wasSilent = this.silent; - this.silent = silent; - return wasSilent; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FailedOperationException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FailedOperationException.java deleted file mode 100644 index e43b7c2ca125..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FailedOperationException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * General wrapping exception for conditions that should terminate the installation process. As a - * rule, errors identified by the Installer should throw this exception. The installer code should - * not throw IOExceptions for anything except real I/O operations. - */ -public class FailedOperationException extends InstallerStopException { - - private static final long serialVersionUID = 1L; - - public FailedOperationException(String message) { - super(message); - } - - public FailedOperationException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Feedback.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Feedback.java deleted file mode 100644 index 527defa07979..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Feedback.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.net.URL; -import java.nio.file.Path; -import java.util.List; -import java.util.Map; - -/** - * Centralizes feedback from individual commands. Allows to centrally handle verbosity, stacktraces - * of exceptions etc. Allows to work with different Bundles. - */ -public interface Feedback { - /** - * Returned from {@link #acceptLine} for an automatic accept. - */ - String AUTO_YES = ""; - - /** - * Formats a message on stderr. - * - * @param bundleKey key into the bundle - * @param params optional positional arguments for the message - */ - void message(String bundleKey, Object... params); - - /** - * Formats a message on stdout. - * - * @param bundleKey key into the bundle - * @param params optional positional arguments for the message - */ - void output(String bundleKey, Object... params); - - /** - * Formats a message on stdout; will not print a newline. - * - * @param bundleKey key into the bundle - * @param params optional positional arguments for the message - */ - void outputPart(String bundleKey, Object... params); - - /** - * Formats a verbosePart-level message on stderr. Returns a flag indicating the verbosePart - * level is on - use to bypass verbosePart messages. - *

- * {code null} bundle key can be used to test verbose flag - * - * @param bundleKey key into the bundle, or {@code null} to just return the verbose flag - * @param params optional positional arguments for the message - * @return {@code true}, if the verbosePart message level is on. - */ - boolean verbosePart(String bundleKey, Object... params); - - /** - * Formats a verbosePart-level message on stdout. Returns a flag indicating the verbosePart - * level is on - use to bypass verbosePart messages. - *

- * {code null} bundle key can be used to test verbose flag - * - * @param bundleKey key into the bundle, or {@code null} to just return the verbose flag - * @param params optional positional arguments for the message - * @return {@code true}, if the verbosePart message level is on. - */ - boolean verboseOutput(String bundleKey, Object... params); - - /** - * Formats an error message on stderr. Depending on settings, the exception stacktrace may be - * printed. - * - * @param bundleKey key into the bundle - * @param params optional positional arguments for the message - * @param t thrown exception. - */ - void error(String bundleKey, Throwable t, Object... params); - - /** - * Formats a message using the bundle. - * - * @param bundleKey key into the bundle - * @param params optional positional arguments for the message - * @return formatted message - */ - String l10n(String bundleKey, Object... params); - - /** - * Reports a message with possible Throwable and wraps it into a - * {@link FailedOperationException}. The caller may directly {@code throw} the result. - * - * @param bundleKey key into the bundle - * @param params optional positional arguments for the message - * @param t thrown exception. - */ - RuntimeException failure(String bundleKey, Throwable t, Object... params); - - /** - * Produces a Feedback instance, which uses different Bundle. Bundle is taken from the package - * of the "clazz". - * - * @param clazz reference class to locate the budle - * @return Feedback which translates through the Bundle - */ - Feedback withBundle(Class clazz); - - /** - * Prints a verbatim message. - * - * @param msg prints the message verbatim - * @param verbose true, if this is only verbosePart - */ - boolean verbatimOut(String msg, boolean verbose); - - boolean verbatimPart(String msg, boolean verbose); - - boolean verbatimPart(String msg, boolean error, boolean verbose); - - boolean backspace(int chars, boolean beVerbose); - - boolean isNonInteractive(); - - boolean isSilent(); - - boolean setSilent(boolean silent); - - default void suppressSilent(Runnable run) { - boolean wasSilent = setSilent(false); - try { - run.run(); - } finally { - setSilent(wasSilent); - } - } - - /** - * Waits for user input confirmed by ENTER. - * - * @param autoYes returns the {@link #AUTO_YES} if yes-to-all was specified on commandline. - * @return accepted line. - */ - String acceptLine(boolean autoYes); - - /** - * Allows to enter password using console services. - * - * @return password - */ - char[] acceptPassword(); - - /** - * Provides a cache for remote files. The URL contents should be downloaded and stored to the - * `local` file. The file should be marked with {@link java.io.File#deleteOnExit()}. - * - * @param location remote location - * @param local locally cached content - */ - void addLocalFileCache(URL location, Path local); - - /** - * Returns a local cache for the location. Returns {@code null}, if the content is not locally - * available. - * - * @param location the remote location - * @return locally stored content or {@code null}. - */ - Path getLocalCache(URL location); - - /** - * Provides a cache for remote files response headers. - * - * @param location remote location - * @param local locally response headers - */ - void addLocalResponseHeadersCache(URL location, Map> local); - - /** - * Returns a local response headers cache for the location. Returns {@code null}, if the content - * is not locally available. - * - * @param location the remote location - * @return locally stored response headers or {@code null}. - */ - Map> getLocalResponseHeadersCache(URL location); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileIterable.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileIterable.java deleted file mode 100644 index 285173483fbb..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileIterable.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.StandardOpenOption; -import java.util.Iterator; -import java.util.ServiceLoader; -import org.graalvm.component.installer.persist.MetadataLoader; - -public class FileIterable extends AbstractIterable { - public FileIterable(CommandInput input, Feedback fb) { - super(input, fb); - } - - private File getFile(String pathSpec) { - File f = new File(pathSpec); - if (f.exists()) { - return f; - } - throw feedback.failure("ERROR_MissingFile", null, pathSpec); - } - - @Override - public Iterator iterator() { - return new Iterator<>() { - @Override - public boolean hasNext() { - return input.hasParameter(); - } - - @Override - public ComponentParam next() { - return new FileComponent(getFile(input.requiredParameter()), isVerifyJars(), null, feedback); - } - }; - } - - public static class FileComponent implements ComponentParam { - private final File localFile; - private MetadataLoader loader; - private final boolean verifyJars; - private final Feedback feedback; - private final String serial; - - /** - * Creates a file-based component. - * - * @param localFile local file to load from - * @param verifyJars true, if the jar signature should be verified - * @param serial serial / tag of the component; if {@code null}, will be computed as sha256 - * hash. - * @param feedback output - */ - public FileComponent(File localFile, boolean verifyJars, String serial, Feedback feedback) { - this.localFile = localFile; - this.verifyJars = verifyJars; - this.serial = serial; - this.feedback = feedback.withBundle(FileComponent.class); - } - - @Override - public MetadataLoader createMetaLoader() throws IOException { - if (loader != null) { - return loader; - } - byte[] fileStart = null; - String ser; - - if (localFile.isFile()) { - try (ReadableByteChannel ch = FileChannel.open(localFile.toPath(), StandardOpenOption.READ)) { - ByteBuffer bb = ByteBuffer.allocate(8); - ch.read(bb); - fileStart = bb.array(); - } - if (serial != null) { - ser = serial; - } else { - ser = SystemUtils.fingerPrint(SystemUtils.computeFileDigest(localFile.toPath(), null), false); - } - } else { - fileStart = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; - ser = ""; - } - - for (ComponentArchiveReader provider : ServiceLoader.load(ComponentArchiveReader.class)) { - MetadataLoader ldr = provider.createLoader(localFile.toPath(), fileStart, ser, feedback, verifyJars); - if (ldr != null) { - loader = ldr; - return ldr; - } - } - throw feedback.failure("ERROR_UnknownFileFormat", null, localFile.toString()); - } - - @Override - public void close() throws IOException { - if (loader != null) { - loader.close(); - } - } - - @Override - public MetadataLoader createFileLoader() throws IOException { - return createMetaLoader(); - } - - @Override - public boolean isComplete() { - return true; - } - - @Override - public String getSpecification() { - return localFile.toString(); - } - - @Override - public String getDisplayName() { - return localFile.toString(); - } - - @Override - public String getFullPath() { - return localFile.getAbsolutePath(); - } - - @Override - public String getShortName() { - return localFile.getName(); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileOperations.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileOperations.java deleted file mode 100644 index 6bd0deca6687..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/FileOperations.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.AccessDeniedException; -import java.nio.file.FileSystemException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.PosixFilePermission; -import java.util.Set; -import java.util.concurrent.Callable; -import org.graalvm.component.installer.os.DefaultFileOperations; -import org.graalvm.component.installer.os.WindowsFileOperations; -import org.graalvm.nativeimage.ImageInfo; - -/** - * - * @author sdedic - */ -public abstract class FileOperations { - private Feedback feedback; - private Path rootPath; - - public void init(Feedback fb) { - this.feedback = fb; - } - - protected final Feedback feedback() { - return feedback; - } - - protected final Path rootPath() { - return rootPath; - } - - public abstract boolean flush() throws IOException; - - /** - * Materializes the path. The input path is relative to the root; the path will be resolved - * against the root. Then, if copy-on-write was performed, the path will be redirected to a - * sibling directory. - * - * @param p the path to materialize - * - * @return the target path or {@code null} - */ - @SuppressWarnings("unused") - public Path materialize(Path p, boolean write) { - return p; - } - - protected void performDelete(Path p) throws IOException { - Files.deleteIfExists(p); - } - - protected abstract boolean doWithPermissions(Path p, Callable action) throws IOException; - - @SuppressWarnings("unused") - protected void handleUndeletableFile(IOException ex, Path p) throws IOException { - throw ex; - } - - @SuppressWarnings("unused") - protected Path handleUnmodifiableFile(IOException ex, Path p, InputStream content) throws IOException { - throw ex; - } - - private void deleteOneFile(Path p, Path rp) throws IOException { - try { - if (p.equals(rp)) { - return; - } - performDelete(p); - } catch (AccessDeniedException ex) { - if (!doWithPermissions(p, () -> { - performDelete(p); - return null; - })) { - throw ex; - } - } catch (FileSystemException ex) { - handleUndeletableFile(ex, p); - } - } - - /** - * Deletes a path relative to the installation root. - *

- * If the operation fails, the implementation will create a sibling of the owning - * directory and copies all files into it, preserving timestamps and access rights, if - * possible. The file to be deleted will not be added to the copied directory. - *

- *

- * Although the delete fails, if the copy-on-write succeeds, the operation reports overall - * success. - * - * @param p path to delete - * @throws IOException - */ - public void deleteFile(Path p) throws IOException { - deleteOneFile(p, rootPath); - } - - protected void performInstall(Path target, InputStream contents) throws IOException { - Files.copy(contents, target, StandardCopyOption.REPLACE_EXISTING); - } - - /** - * Installs a file, potentially replacing an existing file. - * - * @param target - * @throws IOException - */ - public Path installFile(Path target, InputStream contents) throws IOException { - Path ret = target; - try { - performInstall(target, contents); - } catch (AccessDeniedException ex) { - doWithPermissions(target, () -> { - performInstall(target, contents); - return null; - }); - } catch (FileSystemException ex) { - ret = handleUnmodifiableFile(ex, target, contents); - } - return ret; - } - - public Path getRootPath() { - return rootPath; - } - - public void setRootPath(Path rootPath) { - this.rootPath = rootPath; - } - - public abstract void setPermissions(Path target, Set perms) throws IOException; - - public static FileOperations createPlatformInstance(Feedback f, Path rootPath) { - FileOperations inst; - if (SystemUtils.isWindows()) { - WindowsFileOperations w = new WindowsFileOperations(); - inst = w; - if (!ImageInfo.inImageCode()) { - w.setDelayDeletedList(SystemUtils.fromUserString(System.getenv(CommonConstants.ENV_DELETE_LIST))); - w.setCopyContents(SystemUtils.fromUserString(System.getenv(CommonConstants.ENV_COPY_CONTENTS))); - } - } else { - inst = new DefaultFileOperations(); - } - inst.init(f); - inst.setRootPath(rootPath); - return inst; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/GenerateCatalog.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/GenerateCatalog.java deleted file mode 100644 index d198e3a6f114..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/GenerateCatalog.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import static org.graalvm.component.installer.BundleConstants.GRAALVM_CAPABILITY; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.ComponentPackageLoader; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * - * @author sdedic - */ -public final class GenerateCatalog { - private List params = new ArrayList<>(); - private List locations = new ArrayList<>(); - private String graalVersionPrefix; - private String graalVersionName; - private String forceVersion; - private String forceOS; - private String forceVariant; - private String forceArch; - private String urlPrefix; - private final StringBuilder catalogContents = new StringBuilder(); - private final StringBuilder catalogHeader = new StringBuilder(); - private Environment env; - private String graalNameFormatString = "GraalVM %s %s%s/%s"; - private String graalVersionFormatString; - - private static final Map OPTIONS = new HashMap<>(); - - private static final String OPT_FORMAT_1 = "1"; // NOI18N - private static final String OPT_FORMAT_2 = "2"; // NOI18N - private static final String OPT_VERBOSE = "v"; // NOI18N - private static final String OPT_GRAAL_PREFIX = "g"; // NOI18N - private static final String OPT_GRAAL_NAME = "n"; // NOI18N - private static final String OPT_GRAAL_NAME_FORMAT = "f"; // NOI18N - private static final String OPT_URL_BASE = "b"; // NOI18N - private static final String OPT_PATH_BASE = "p"; // NOI18N - private static final String OPT_FORCE_VERSION = "e"; // NO18N - private static final String OPT_FORCE_OS = "o"; // NO18N - private static final String OPT_FORCE_VARIANT = "V"; // NO18N - private static final String OPT_FORCE_ARCH = "a"; // NO18N - private static final String OPT_SEARCH_LOCATION = "l"; // NOI18N - - static { - OPTIONS.put(OPT_FORMAT_1, ""); // format v1 < GraalVM 1.0.0-rc16+ - OPTIONS.put(OPT_FORMAT_2, ""); // format v2 = GraalVM 1.0.0-rc16+ - OPTIONS.put(OPT_VERBOSE, ""); // verbose - OPTIONS.put(OPT_GRAAL_PREFIX, "s"); - OPTIONS.put(OPT_FORCE_VERSION, "s"); - OPTIONS.put(OPT_FORCE_OS, "s"); - OPTIONS.put(OPT_FORCE_VARIANT, "s"); - OPTIONS.put(OPT_GRAAL_NAME_FORMAT, "s"); - OPTIONS.put(OPT_GRAAL_NAME, "s"); - OPTIONS.put(OPT_FORCE_ARCH, "s"); - OPTIONS.put(OPT_GRAAL_NAME, ""); // GraalVM release name - OPTIONS.put(OPT_URL_BASE, "s"); // URL Base - OPTIONS.put(OPT_PATH_BASE, "s"); // fileName base - OPTIONS.put(OPT_SEARCH_LOCATION, "s"); // list files - } - - private Map graalVMReleases = new LinkedHashMap<>(); - - public static void main(String[] args) throws IOException { - new GenerateCatalog(args).run(); - System.exit(0); - } - - private GenerateCatalog(String[] args) { - this.params = new ArrayList<>(Arrays.asList(args)); - } - - private static byte[] computeHash(File f) throws IOException { - MessageDigest fileDigest; - try { - fileDigest = MessageDigest.getInstance("SHA-256"); // NOI18N - } catch (NoSuchAlgorithmException ex) { - throw new IOException("Cannot compute digest " + ex.getLocalizedMessage(), ex); - } - ByteBuffer bb = ByteBuffer.allocate(2048); - boolean updated = false; - try ( - InputStream is = new FileInputStream(f); - ReadableByteChannel bch = Channels.newChannel(is)) { - int read; - while (true) { - read = bch.read(bb); - if (read < 0) { - break; - } - bb.flip(); - fileDigest.update(bb); - bb.clear(); - updated = true; - } - } - if (!updated) { - fileDigest.update(new byte[0]); - } - - return fileDigest.digest(); - } - - static String digest2String(byte[] digest) { - StringBuilder sb = new StringBuilder(digest.length * 3); - for (int i = 0; i < digest.length; i++) { - sb.append(String.format("%02x", (digest[i] & 0xff))); - } - return sb.toString(); - } - - static class Spec { - File f; - String u; - String relativePath; - - Spec(File f, String u) { - this.f = f; - this.u = u; - } - } - - static class GraalVersion { - String version; - String os; - String variant; - String arch; - - GraalVersion(String version, String os, String variant, String arch) { - this.version = version; - this.os = os; - this.variant = variant; - this.arch = arch; - } - - } - - private List componentSpecs = new ArrayList<>(); - - private Path pathBase = null; - - public void run() throws IOException { - readCommandLine(); - downloadFiles(); - generateCatalog(); - generateReleases(); - - System.out.println(catalogHeader); - System.out.println(catalogContents); - } - - private void readCommandLine() throws IOException { - SimpleGetopt getopt = new SimpleGetopt(OPTIONS) { - @Override - public RuntimeException err(String messageKey, Object... args) { - ComponentInstaller.printErr(messageKey, args); - System.exit(1); - return null; - } - }.ignoreUnknownCommands(true); - getopt.setParameters(new LinkedList<>(params)); - getopt.process(); - this.env = new Environment(null, getopt.getPositionalParameters(), getopt.getOptValues()); - this.env.setAllOutputToErr(true); - - String pb = env.optValue(OPT_PATH_BASE); - if (pb != null) { - pathBase = SystemUtils.fromUserString(pb).toAbsolutePath(); - } - urlPrefix = env.optValue(OPT_URL_BASE); - graalVersionPrefix = env.optValue(OPT_GRAAL_PREFIX); - if (graalVersionPrefix != null) { - graalVersionName = env.optValue(OPT_GRAAL_NAME); - if (graalVersionName == null) { - throw new IOException("Graal prefix specified, but no human-readable name"); - } - } - forceVersion = env.optValue(OPT_FORCE_VERSION); - forceOS = env.optValue(OPT_FORCE_OS); - forceVariant = env.optValue(OPT_FORCE_VARIANT); - forceArch = env.optValue(OPT_FORCE_ARCH); - if (env.hasOption(OPT_FORMAT_1)) { - formatVer = 1; - } else if (env.hasOption(OPT_FORMAT_2)) { - formatVer = 2; - } - String s = env.optValue(OPT_GRAAL_NAME_FORMAT); - if (s != null) { - graalNameFormatString = s; - } - - switch (formatVer) { - case 1: - graalVersionFormatString = "%s_%s%s_%s"; - break; - case 2: - graalVersionFormatString = "%2$s%3$s_%4$s/%1$s"; - break; - default: - throw new IllegalStateException(); - } - - if (env.hasOption(OPT_SEARCH_LOCATION)) { - Path listFrom = Paths.get(env.optValue("l")); - Files.walk(listFrom).filter((p) -> p.toString().endsWith(".jar")).forEach( - (p) -> locations.add(p.toString())); - } - // process the rest of non-options parameters as locations. - while (env.hasParameter()) { - locations.add(env.nextParameter()); - } - - for (String spec : locations) { - File f = null; - String u = null; - - int eq = spec.indexOf('='); - if (eq != -1) { - f = new File(spec.substring(0, eq)); - if (!f.exists()) { - throw new FileNotFoundException(f.toString()); - } - String uriPart = spec.substring(eq + 1); - u = uriPart; - } else { - f = new File(spec); - if (!f.exists()) { - f = null; - u = spec; - // create a URL, just to fail fast, if the URL is wrong: - URL check = SystemUtils.toURL(spec); - // ... and use it somehow, so ECJ does not fail the gate. - assert check.toString() != null; - } - } - addComponentSpec(f, u); - } - } - - private void addComponentSpec(File f, String u) { - Spec spc = new Spec(f, u); - if (f != null) { - if (pathBase != null) { - spc.relativePath = pathBase.relativize(f.toPath().toAbsolutePath()).toString(); - } - } - componentSpecs.add(spc); - } - - private URL createURL(String spec) throws MalformedURLException { - if (urlPrefix != null) { - return SystemUtils.toURL(urlPrefix, spec); - } else { - return SystemUtils.toURL(spec); - } - } - - private void downloadFiles() throws IOException { - for (Spec spec : componentSpecs) { - if (spec.f == null) { - FileDownloader dn = new FileDownloader(spec.u, createURL(spec.u), env); - dn.setDisplayProgress(true); - dn.download(); - spec.f = dn.getLocalFile(); - } - } - } - - private String os; - private String variant; - private String arch; - private String version; - private int formatVer = 1; - - private String findComponentPrefix(ComponentInfo info) { - Map m = info.getRequiredGraalValues(); - if (graalVersionPrefix != null) { - arch = os = variant = null; - version = graalVersionPrefix; - return graalVersionPrefix; - } - if (forceVersion != null) { - version = forceVersion; - } else { - switch (formatVer) { - case 1: - version = info.getVersionString(); - break; - case 2: - version = info.getVersion().toString(); - break; - } - } - String var = forceVariant != null ? forceVariant : m.get(CommonConstants.CAP_OS_VARIANT); - return String.format(graalVersionFormatString, - version, - os = forceOS != null ? forceOS : m.get(CommonConstants.CAP_OS_NAME), - variant = var == null || var.isEmpty() ? "" : "_" + var, - arch = forceArch != null ? forceArch : m.get(CommonConstants.CAP_OS_ARCH)); - } - - private void generateReleases() { - for (String prefix : graalVMReleases.keySet()) { - GraalVersion ver = graalVMReleases.get(prefix); - String vprefix; - String n; - if (ver.os == null) { - vprefix = graalVersionPrefix; - n = graalVersionName; - } else { - // do not use serial for releases. - vprefix = String.format(graalVersionFormatString, ver.version, ver.os, ver.variant, ver.arch); - n = String.format(graalNameFormatString, ver.version, ver.os, ver.variant, ver.arch); - } - catalogHeader.append(GRAALVM_CAPABILITY).append('.').append(vprefix).append('=').append(n).append('\n'); - if (ver.os == null) { - break; - } - } - } - - private void generateCatalog() throws IOException { - for (Spec spec : componentSpecs) { - File f = spec.f; - byte[] hash = computeHash(f); - String hashString = digest2String(hash); - try (JarFile jf = new JarFile(f)) { - ComponentPackageLoader ldr = new JarMetaLoader(jf, hashString, env); - ComponentInfo info = ldr.createComponentInfo(); - String prefix = findComponentPrefix(info); - if (!graalVMReleases.containsKey(prefix)) { - graalVMReleases.put(prefix, new GraalVersion(version, os, variant, arch)); - } - Manifest mf = jf.getManifest(); - if (mf == null) { - throw new IOException("No manifest in " + spec); - } - String tagString; - - if (formatVer < 2 || info.getTag() == null || info.getTag().isEmpty()) { - tagString = ""; - } else { - // include hash of the file in property prefix. - tagString = "/" + hashString; // NOI18N - } - Attributes atts = mf.getMainAttributes(); - String bid = atts.getValue(BundleConstants.BUNDLE_ID).toLowerCase().replace("-", "_"); - String bl = atts.getValue(BundleConstants.BUNDLE_NAME); - - if (bid == null) { - throw new IOException("Missing bundle id in " + spec); - } - if (bl == null) { - throw new IOException("Missing bundle name in " + spec); - } - String name; - prefix += tagString; - if (spec.u != null) { - name = spec.u.toString(); - } else { - name = spec.relativePath != null ? spec.relativePath : f.getName(); - } - int pos; - while ((pos = name.indexOf("${")) != -1) { - int endPos = name.indexOf("}", pos + 1); - if (endPos == -1) { - break; - } - String key = name.substring(pos + 2, endPos); - String repl = info.getRequiredGraalValues().get(key); - if (repl == null) { - switch (key) { - case "version": - repl = version; - break; - case "os": - repl = os; - break; - case "arch": - repl = arch; - break; - case "comp_version": - repl = info.getVersionString(); - break; - default: - throw new IllegalArgumentException(key); - } - } - if (repl == null) { - throw new IllegalArgumentException(key); - } - String toReplace = "${" + key + "}"; - name = name.replace(toReplace, repl); - } - String url = (urlPrefix == null || urlPrefix.isEmpty()) ? name : urlPrefix + "/" + name; - String sel; - String hashSuffix; - - switch (formatVer) { - case 1: - sel = "Component.{0}.{1}"; - hashSuffix = "-hash"; - break; - case 2: - sel = "Component.{0}/{1}"; - hashSuffix = "-hash"; - break; - default: - throw new IllegalStateException(); - } - catalogContents.append(MessageFormat.format( - sel + "={2}\n", prefix, bid, url)); - catalogContents.append(MessageFormat.format( - sel + hashSuffix + "={2}\n", prefix, bid, hashString)); - - for (Object a : atts.keySet()) { - String key = a.toString(); - String val = atts.getValue(key); - if (key.startsWith("x-GraalVM-Message-")) { // NOI18N - continue; - } - catalogContents.append(MessageFormat.format( - sel + "-{2}={3}\n", prefix, bid, key, val)); - } - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/IncompatibleException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/IncompatibleException.java deleted file mode 100644 index 4b80e8d3b7b2..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/IncompatibleException.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * - * @author sdedic - */ -public class IncompatibleException extends InstallerStopException { - private static final long serialVersionUID = 23L; - - public IncompatibleException(String message) { - super(message); - } - - public IncompatibleException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerCommand.java deleted file mode 100644 index 2533800328f2..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.util.Map; - -/** - * Interface for individual commands. - */ -public interface InstallerCommand { - /** - * Provides supported options for the command. The installer will fail if other options are - * specified on commandline than listed here. Place option specification into the Map under the - * option name's key. Parametrized options are not supported at this moment. Use empty string - * for parameter-less options. - * - * @return supported options - */ - Map supportedOptions(); - - /** - * Executes a command. - * - * @param commandInput access to parameters, options - * @param feedBack output interface, use instead of Stderr, Stdout - */ - void init(CommandInput commandInput, Feedback feedBack); - - /** - * Executes a command. - * - * @throws IOException if file-level operation fails. - */ - int execute() throws IOException; -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerStopException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerStopException.java deleted file mode 100644 index 21d43a840c26..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/InstallerStopException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Exception which will stop the installer operation. Root of {@link RuntimeException}s, which - * should be reported as "normal errors". Other RuntimeExceptions will be reported as internal - * errors (bugs). - */ -public abstract class InstallerStopException extends RuntimeException { - private static final long serialVersionUID = 1L; - - public InstallerStopException(String message) { - super(message); - } - - public InstallerStopException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/MetadataException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/MetadataException.java deleted file mode 100644 index 21f8bea56538..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/MetadataException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Represents a corrupted metadata condition. - */ -public class MetadataException extends InstallerStopException { - private static final long serialVersionUID = 1L; - private final String offendingHeader; - - public MetadataException(String offendingHeader, String message) { - super(message); - this.offendingHeader = offendingHeader; - } - - public String getOffendingHeader() { - return offendingHeader; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/NonInteractiveException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/NonInteractiveException.java deleted file mode 100644 index 2a81971222f1..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/NonInteractiveException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Represents a failure when a non-interactive mode required user input. - * - * @author sdedic - */ -public class NonInteractiveException extends InstallerStopException { - private static final long serialVersionUID = 2L; - - public NonInteractiveException(String message) { - super(message); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SimpleGetopt.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SimpleGetopt.java deleted file mode 100644 index 6dd3d56e2cfc..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SimpleGetopt.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import static org.graalvm.component.installer.Commands.DO_NOT_PROCESS_OPTIONS; - -/** - * - * @author sdedic - */ -public class SimpleGetopt { - private LinkedList parameters; - private final Map globalOptions; - private final Map> commandOptions = new HashMap<>(); - - private final Map optValues = new HashMap<>(); - private final LinkedList positionalParameters = new LinkedList<>(); - - private String command; - private boolean ignoreUnknownCommands; - private boolean unknownCommand; - - private List unknownOptions; - - private Map abbreviations = new HashMap<>(); - private final Map> commandAbbreviations = new HashMap<>(); - - public SimpleGetopt(Map globalOptions) { - this.globalOptions = globalOptions; - } - - public void setParameters(LinkedList parameters) { - this.parameters = parameters; - } - - public SimpleGetopt ignoreUnknownOptions(boolean ignore) { - this.unknownOptions = ignore ? new ArrayList<>() : null; - return this; - } - - public SimpleGetopt ignoreUnknownCommands(boolean ignore) { - this.ignoreUnknownCommands = ignore; - return this; - } - - public List getUnknownOptions() { - return unknownOptions == null ? Collections.emptyList() : unknownOptions; - } - - // overridable by tests - public RuntimeException err(String messageKey, Object... args) { - throw ComponentInstaller.err(messageKey, args); - } - - private String findCommand(String cmdString) { - String cmd = cmdString; - if (cmd.isEmpty()) { - if (ignoreUnknownCommands) { - return null; - } - throw err("ERROR_MissingCommand"); // NOI18N - } - String selCommand = null; - for (String s : commandOptions.keySet()) { - if (s.startsWith(cmdString)) { - if (selCommand != null) { - throw err("ERROR_AmbiguousCommand", cmdString, selCommand, s); - } - selCommand = s; - if (s.length() == cmdString.length()) { - break; - } - } - } - if (selCommand == null) { - if (ignoreUnknownCommands) { - unknownCommand = true; - command = cmdString; - return null; - } - throw err("ERROR_UnknownCommand", cmdString); // NOI18N - } - command = selCommand; - return command; - } - - private static final String NO_ABBREV = "**no-abbrev"; // NOI18N - - private boolean hasCommand() { - return command != null && !unknownCommand; - } - - @SuppressWarnings("StringEquality") - Map computeAbbreviations(Collection optNames) { - Map result = new HashMap<>(); - - for (String o : optNames) { - if (o.length() < 2) { - continue; - } - result.put(o, NO_ABBREV); - for (int i = 2; i < o.length(); i++) { - String s = o.substring(0, i); - - String fullName = result.get(s); - if (fullName == null) { - result.put(s, o); - } else { - result.put(s, NO_ABBREV); - } - } - } - // final Object noAbbrevMark = NO_ABBREV; - for (Iterator> ens = result.entrySet().iterator(); ens.hasNext();) { - Entry en = ens.next(); - // cannot use comparison to NO_ABBREV directly because of FindBugs + mx gate combo. - if (NO_ABBREV.equals(en.getValue())) { - ens.remove(); - } - } - return result; - } - - Collection getAllOptions() { - Set s = new HashSet<>(); - s.addAll(globalOptions.keySet()); - for (Map cmdOpts : commandOptions.values()) { - s.addAll(cmdOpts.keySet()); - } - // discard short option stubs when only long option exists. - for (Iterator it = s.iterator(); it.hasNext();) { - String opt = it.next(); - if (opt.length() == 1 && !Character.isLetterOrDigit(opt.charAt(0))) { - it.remove(); - } - } - return s; - } - - void computeAbbreviations() { - abbreviations = computeAbbreviations(globalOptions.keySet()); - - for (String c : commandOptions.keySet()) { - Set names = new HashSet<>(commandOptions.get(c).keySet()); - names.addAll(globalOptions.keySet()); - - Map commandAbbrevs = computeAbbreviations(names); - commandAbbreviations.put(c, commandAbbrevs); - } - } - - public void process() { - computeAbbreviations(); - while (true) { - String p = parameters.peek(); - if (p == null) { - break; - } - if (!p.startsWith("-")) { // NOI18N - if (command == null) { - findCommand(parameters.poll()); - Map cOpts = commandOptions.get(command); - if (cOpts != null) { - for (String s : optValues.keySet()) { - if (s.length() > 1) { - continue; - } - if ("X".equals(cOpts.get(s))) { - unknownOption(s, command); - break; - } - } - if (cOpts.containsKey(DO_NOT_PROCESS_OPTIONS)) { // NOI18N - // terminate all processing, the rest are positional params - positionalParameters.addAll(parameters); - break; - } - } else { - positionalParameters.add(p); - } - } else { - positionalParameters.add(parameters.poll()); - } - continue; - } else if (p.length() == 1 || "--".equals(p)) { - // dash alone, or double-dash terminates option search. - parameters.poll(); - positionalParameters.addAll(parameters); - break; - } - String param = parameters.poll(); - boolean nextParam = p.startsWith("--"); // NOI18N - String optName; - int optCharIndex = 1; - while (optCharIndex < param.length()) { - if (nextParam) { - optName = param.substring(2); - param = processOptSpec(optName, optCharIndex, param, nextParam); - } else { - optName = param.substring(optCharIndex, optCharIndex + 1); - optCharIndex += optName.length(); - param = processOptSpec(optName, optCharIndex, param, nextParam); - } - // hack: if "help" option (hardcoded) is present, terminate - if (optValues.get("h") != null) { - return; - } - if (nextParam) { - break; - } - } - } - } - - private void unknownOption(String option, String cmd) { - if (unknownOptions == null) { - if (cmd == null) { - throw err("ERROR_UnsupportedGlobalOption", option); // NOI18N - } else { - throw err("ERROR_UnsupportedOption", option, cmd); // NOI18N - } - } else { - unknownOptions.add(option); - } - - } - - private String processOptSpec(String o, int optCharIndex, String optParam, boolean nextParam) { - String param = optParam; - String optSpec = null; - String optName = o; - Map cmdSpec = null; - - if (hasCommand()) { - Map cmdAbbrevs = commandAbbreviations.get(command); - String fullO = cmdAbbrevs.get(optName); - if (fullO != null) { - optName = fullO; - } - cmdSpec = commandOptions.get(command); - String c = cmdSpec.get(optName); - if (c != null && optName.length() > 1) { - optSpec = cmdSpec.get(c); - optName = c; - } else { - optSpec = c; - } - } - if (optSpec == null) { - String fullO = abbreviations.get(optName); - if (fullO != null) { - optName = fullO; - } - String c = globalOptions.get(optName); - if (c != null && optName.length() > 1) { - optSpec = globalOptions.get(c); - optName = c; - } else { - optSpec = c; - } - } - if (optSpec != null && optSpec.startsWith("=")) { - String s = optSpec.substring(1); - String nspec = null; - if (cmdSpec != null) { - nspec = cmdSpec.get(s); - } - if (nspec == null) { - nspec = globalOptions.get(s); - } - if (nspec != null) { - optSpec = nspec; - optName = s; - } - } - if (optSpec == null) { - if (unknownCommand) { - return param; - } - unknownOption(optName, command); - return param; - } - // no support for parametrized options now - String optVal = ""; - switch (optSpec) { - case "s": - if (nextParam) { - optVal = parameters.poll(); - if (optVal == null) { - throw err("ERROR_OptionNeedsParameter", o, command); // NOI18N - } - } else { - if (optCharIndex < param.length()) { - optVal = param.substring(optCharIndex); - param = ""; - } else if (parameters.isEmpty()) { - throw err("ERROR_OptionNeedsParameter", o, command); // NOI18N - } else { - optVal = parameters.poll(); - } - } - break; - case "X": - unknownOption(o, command); - return param; - case "": - break; - } - optValues.put(optName, optVal); // NOI18N - return param; - } - - public String getCommand() { - return command; - } - - public void addCommandOptions(String commandName, Map optSpec) { - commandOptions.put(commandName, new HashMap<>(optSpec)); - } - - // test only - void addCommandOption(String commandName, String optName, String optVal) { - commandOptions.get(commandName).put(optName, optVal); - } - - public Map getOptValues() { - return optValues; - } - - public LinkedList getPositionalParameters() { - return positionalParameters; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannel.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannel.java deleted file mode 100644 index 5026cba51c26..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannel.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * An abstraction of software delivery channel. The channel provides a Registry of available - * components. It can augment or change the download process and it can interpret the downloaded - * files to support different file formats. - *

- * - * @author sdedic - */ -public interface SoftwareChannel { - /** - * Loads and provides access to the component registry. - * - * @return registry instance ComponentCollection getRegistry(); - */ - - ComponentStorage getStorage() throws IOException; - - /** - * Configures the downloader with specific options. The downloader may be even replaced with a - * different instance. - * - * @param dn the downloader to configure - * @return the downloader instance. - */ - FileDownloader configureDownloader(ComponentInfo info, FileDownloader dn); - - /* - * Checks if the Component can be installed by native tools. In that case, the installer will - * refuse to operate and displays an appropriate error message - * - * @param info - * - * @return boolean isNativeInstallable(ComponentInfo info); - */ - - interface Factory { - /** - * True, if the channel is willing to handle the URL. URL is passed as a String so that - * custom protocols may be used without registering a URLStreamHandlerFactory. - * - * @param source the definition of the channel including label - * @param input input parameters - * @param output output interface - * @return true, if the channel is willing to work with the URL - */ - SoftwareChannel createChannel(SoftwareChannelSource source, CommandInput input, Feedback output); - - /** - * Adds options to the set of global options. Global options allow to accept specific - * options from commandline, which would otherwise cause an error (unknown option). - * - * @return global options to add. - */ - default Map globalOptions() { - return Collections.emptyMap(); - } - - /** - * Provides help for the injected global options. - * - * @return String to append to the displayed help, or {@code null} for empty message. - */ - default String globalOptionsHelp() { - return null; - } - - void init(CommandInput input, Feedback output); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannelSource.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannelSource.java deleted file mode 100644 index 34b3b45aae49..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SoftwareChannelSource.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.HashMap; -import java.util.Map; - -/** - * Description of a component catalog. - * - * @author sdedic - */ -public final class SoftwareChannelSource { - /** - * Access location, represented as String to allow custom protocols without URL protocol - * handler. - */ - private String locationURL; - - /** - * Label for the catalog. - */ - private String label; - - private int priority; - - /** - * Optional parametrs for the software channel. - */ - private Map params = new HashMap<>(); - - public SoftwareChannelSource(String locationURL) { - this.locationURL = SystemUtils.parseURLParameters(locationURL, params); - } - - public SoftwareChannelSource(String locationURL, String label) { - this.locationURL = locationURL; - this.label = label; - } - - public void setLabel(String label) { - this.label = label; - } - - public void setParameter(String param, String value) { - params.put(param, value); - } - - public String getLocationURL() { - return locationURL; - } - - public String getLabel() { - return label; - } - - public String getParameter(String key) { - return params.get(key); - } - - public int getPriority() { - return priority; - } - - public void setPriority(int priority) { - this.priority = priority; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SuppressFBWarnings.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SuppressFBWarnings.java deleted file mode 100644 index 2610de568f9d..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SuppressFBWarnings.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * Used to suppress FindBugs warnings. - */ -public @interface SuppressFBWarnings { - /** - * The set of FindBugs - * warnings that are to be - * suppressed in annotated element. The value can be a bug category, kind or pattern. - */ - String[] value(); - - /** - * Reason why the warning is suppressed. - */ - String justification(); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SystemUtils.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SystemUtils.java deleted file mode 100644 index dfb6100cb81c..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/SystemUtils.java +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import static org.graalvm.component.installer.CommonConstants.ARCH_AARCH64; -import static org.graalvm.component.installer.CommonConstants.ARCH_AMD64; -import static org.graalvm.component.installer.CommonConstants.ARCH_X8664; -import static org.graalvm.component.installer.CommonConstants.CAP_OS_NAME; -import static org.graalvm.component.installer.CommonConstants.OS_MACOS_DARWIN; -import static org.graalvm.component.installer.CommonConstants.OS_TOKEN_LINUX; -import static org.graalvm.component.installer.CommonConstants.OS_TOKEN_MAC; -import static org.graalvm.component.installer.CommonConstants.OS_TOKEN_MACOS; -import static org.graalvm.component.installer.CommonConstants.OS_TOKEN_WINDOWS; -import static org.graalvm.component.installer.CommonConstants.SYSPROP_ARCH_NAME; -import static org.graalvm.component.installer.CommonConstants.SYSPROP_JAVA_VERSION; -import static org.graalvm.component.installer.CommonConstants.SYSPROP_OS_NAME; -import static java.nio.charset.StandardCharsets.UTF_8; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLDecoder; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.nio.file.attribute.AclFileAttributeView; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.PosixFileAttributeView; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.graalvm.component.installer.model.ComponentRegistry; -import java.net.URLEncoder; -import java.util.Collection; -import java.util.Locale; - -/** - * - * @author sdedic - */ -public class SystemUtils { - /** - * Path component delimiter. - */ - public static final char DELIMITER_CHAR = '/'; // NOI18N - - /** - * Path component delimiter. - */ - public static final String DELIMITER = "/"; // NOI18N - - private static final String DOT = "."; // NOI18N - - private static final String DOTDOT = ".."; // NOI18N - - private static final String SPLIT_DELIMITER = Pattern.quote(DELIMITER); - - public enum OS { - WINDOWS(OS_TOKEN_WINDOWS), - LINUX(OS_TOKEN_LINUX), - MAC(OS_TOKEN_MACOS), - UNKNOWN(null); - - private final String name; - - public String getName() { - return name; - } - - OS(String name) { - this.name = name; - } - - public static String sysName() { - return System.getProperty(SYSPROP_OS_NAME); - } - - /** - * Obtains current OS enum. - * - * @return OS enum identifier - */ - public static OS get() { - return fromName(sysName()); - } - - public static OS fromName(String osName) { - return osName == null ? UNKNOWN : fromNameLower(osName.toLowerCase(Locale.ENGLISH)); - } - - private static OS fromNameLower(String osNameLower) { - if (!osNameLower.isBlank()) { - if (osNameLower.contains(OS_TOKEN_WINDOWS)) { - return WINDOWS; - } - if (osNameLower.contains(OS_TOKEN_LINUX)) { - return LINUX; - } - if (osNameLower.contains(OS_TOKEN_MAC) || osNameLower.contains(OS_MACOS_DARWIN)) { - return MAC; - } - } - return UNKNOWN; - } - } - - public enum ARCH { - AMD64(ARCH_AMD64), - AARCH64(ARCH_AARCH64), - UNKNOWN(null); - - private final String name; - - public String getName() { - return name; - } - - ARCH(String name) { - this.name = name; - } - - public static String sysName() { - return System.getProperty(SYSPROP_ARCH_NAME); - } - - /** - * Obtain current ARCH enum. - * - * @return ARCH enum identifier - */ - public static ARCH get() { - return fromName(sysName()); - } - - public static ARCH fromName(String archName) { - return archName == null ? UNKNOWN : fromNameLower(archName.toLowerCase(Locale.ENGLISH)); - } - - private static ARCH fromNameLower(String archNameLower) { - if (!archNameLower.isBlank()) { - if (archNameLower.contains(ARCH_AARCH64)) { - return AARCH64; - } - if (archNameLower.contains(ARCH_AMD64) || archNameLower.contains(ARCH_X8664)) { - return AMD64; - } - } - return UNKNOWN; - } - } - - public static boolean nonBlankString(String string) { - return string != null && !string.isBlank(); - } - - /** - * Creates a proper {@link Path} from string representation. The string representation uses - * forward slashes to delimit fileName components. - * - * @param p the fileName specification - * @return Path instance - */ - public static Path fromCommonString(String p) { - String[] comps = p.split(SPLIT_DELIMITER); - if (comps.length == 1) { - return Paths.get(comps[0]); - } - int l = comps.length - 1; - String s = comps[0]; - System.arraycopy(comps, 1, comps, 0, l); - comps[l] = ""; // NOI18N - return Paths.get(s, comps); - } - - /** - * Creates a fileName from user-provided string. It will split the string according to OS - * fileName component delimiter, then fileName the Path instance - * - * @param p user-provided string, with OS-dependent delimiters - * @return Path that correspond to the user-supplied string - */ - public static Path fromUserString(String p) { - return Paths.get(p); - } - - /** - * Sanity check wrapper around {@link Paths#get}. This wrapper checks that the string does NOT - * contain any fileName component delimiter (slash, backslash). - * - * @param s - * @return Path that corresponds to the filename - */ - public static Path fileName(String s) { - if ((s.indexOf(DELIMITER_CHAR) >= 0) || - ((DELIMITER_CHAR != File.separatorChar) && (s.indexOf(File.separatorChar) >= 0))) { - throw new IllegalArgumentException(s); - } - if (DOT.equals(s) || DOTDOT.equals(s)) { - throw new IllegalArgumentException(s); - } - return Paths.get(s); - } - - /** - * Creates a path string using {@link #DELIMITER_CHAR} as a separator. Returns the same values - * on Windows and UNIXes. - * - * @param p path to convert - * @return path string - */ - public static String toCommonPath(Path p) { - StringBuilder sb = new StringBuilder(); - boolean next = false; - for (Path comp : p) { - if (next) { - sb.append(DELIMITER_CHAR); - } - String compS = comp.toString(); - if (File.separatorChar != DELIMITER_CHAR) { - compS = compS.replace(File.separator, DELIMITER); - } - sb.append(compS); - next = true; - } - return sb.toString(); - } - - /** - * Checks if running on Windows. - * - * @return true, if on Windows. - */ - public static boolean isWindows() { - return OS.get().equals(OS.WINDOWS); - } - - /** - * Checks if running on Linux. - * - * @return true, if on Linux. - */ - public static boolean isLinux() { - return OS.get().equals(OS.LINUX); - } - - /** - * Checks if running on Mac. - * - * @return true, if on Mac. - */ - public static boolean isMac() { - return OS.get().equals(OS.MAC); - } - - /** - * Checks if the path is relative and does not go above its root. The path may contain - * {@code ..} components, but they must not traverse outside the relative subtree. - * - * @param p the path, in common notation (slashes) - * @return the path - * @trows IllegalArgumentException if the path is invalid - */ - public static Path fromCommonRelative(String p) { - if (p == null) { - return null; - } - return fromArray(checkRelativePath(null, p)); - } - - private static Path fromArray(String[] comps) { - if (comps.length == 1) { - return Paths.get(comps[0]); - } - int l = comps.length - 1; - String s = comps[0]; - System.arraycopy(comps, 1, comps, 0, l); - comps[l] = ""; // NOI18N - return Paths.get(s, comps); - } - - public static Path resolveRelative(Path baseDir, String p) { - if (baseDir == null) { - return null; - } - if (p == null) { - return null; - } - String[] comps = checkRelativePath(baseDir, p); - return baseDir.resolve(fromArray(comps)); - } - - public static Path fromCommonRelative(Path base, String p) { - if (p == null) { - return null; - } else if (base == null) { - return fromCommonRelative(p); - } - String[] comps = checkRelativePath(base, p); - return base.resolveSibling(fromArray(comps)); - } - - /** - * Resolves a relative path against a base, does not allow the path to go above the base root. - * - * @param base base Path - * @param p path string - * @throws IllegalArgumentException on invalid path - */ - public static void checkCommonRelative(Path base, String p) { - if (p == null) { - return; - } - checkRelativePath(base, p); - } - - private static String[] checkRelativePath(Path base, String p) { - if (p.startsWith(DELIMITER)) { - throw new IllegalArgumentException("Absolute path"); - } - String[] comps = p.split(SPLIT_DELIMITER); - int d = base == null ? 0 : base.normalize().getNameCount() - 1; - int fromIndex = 0; - int toIndex = 0; - for (String s : comps) { - if (s.isEmpty()) { - fromIndex++; - continue; - } - if (DOTDOT.equals(s)) { - d--; - if (d < 0) { - throw new IllegalArgumentException("Relative path reaches above root"); - } - } else { - d++; - } - if (toIndex < fromIndex) { - comps[toIndex] = comps[fromIndex]; - } - fromIndex++; - toIndex++; - } - if (fromIndex == toIndex) { - return comps; - } else { - // return without the empty parts - String[] newcomps = new String[toIndex]; - System.arraycopy(comps, 0, newcomps, 0, toIndex); - return newcomps; - } - } - - private static final Pattern OLD_VERSION_PATTERN = Pattern.compile("([0-9]+\\.[0-9]+(\\.[0-9]+)?(\\.[0-9]+)?)(-([a-z]+)([0-9]+)?)?"); - - /** - * Will transform some widely used formats to RPM-style. Currently it transforms: - *

    - *
  • 1.0.1-dev[.x] => 1.0.1.0-0.dev[.x] - *
  • 1.0.0 => 1.0.0.0 - *
- * - * @param v - * @return normalized version - */ - public static String normalizeOldVersions(String v) { - if (v == null) { - return null; - } - Matcher m = OLD_VERSION_PATTERN.matcher(v); - if (!m.matches()) { - return v; - } - String numbers = m.group(1); - String rel = m.group(5); - String relNo = m.group(6); - - if (numbers.startsWith("0.")) { - return v; - } - - if (rel == null) { - if (m.group(3) == null) { - return numbers + ".0"; - } else { - return numbers; - } - } else { - if (m.group(3) == null) { - numbers = numbers + ".0"; - } - return numbers + "-0." + rel + (relNo == null ? "" : "." + relNo); - } - } - - public static Path getGraalVMJDKRoot(ComponentRegistry reg) { - if (OS.MAC.equals(OS.fromName(reg.getGraalCapabilities().get(CAP_OS_NAME)))) { - return Paths.get("Contents", "Home"); - } else { - return Paths.get(""); - } - } - - /** - * Finds a file owner. On POSIX systems, returns owner of the file. On Windows (ACL fs view) - * returns the owner principal's name. - * - * @param file the file to test - * @return owner name - */ - public static String findFileOwner(Path file) throws IOException { - PosixFileAttributeView posix = file.getFileSystem().provider().getFileAttributeView(file, PosixFileAttributeView.class); - if (posix != null) { - return posix.getOwner().getName(); - } - AclFileAttributeView acl = file.getFileSystem().provider().getFileAttributeView(file, AclFileAttributeView.class); - if (acl != null) { - return acl.getOwner().getName(); - } - return null; - } - - static boolean licenseTracking = false; - - public static boolean isLicenseTrackingEnabled() { - return licenseTracking; - } - - public static String parseURLParameters(String s, Map params) { - int q = s.indexOf('?'); // NOI18N - if (q == -1) { - return s; - } - String queryString = s.substring(q + 1); - for (String parSpec : queryString.split("&")) { // NOI18N - String[] nameAndVal = parSpec.split("="); // NOI18N - String n; - String v; - - n = URLDecoder.decode(nameAndVal[0], UTF_8); - if (n.isEmpty()) { - continue; - } - v = nameAndVal.length > 1 ? URLDecoder.decode(nameAndVal[1], UTF_8) : ""; - params.put(n, v); - } - return s.substring(0, q); - } - - public static int getJavaMajorVersion(CommandInput cmd) { - String v = cmd.getLocalRegistry() != null ? cmd.getLocalRegistry().getJavaVersion() : null; - if (v == null) { - cmd.getParameter(SYSPROP_JAVA_VERSION, true); - } - if (v != null) { - return interpretJavaMajorVersion(v); - } else { - return getJavaMajorVersion(); - } - } - - public static String buildUrlStringWithParameters(String baseURL, Map> params) { - if (params == null || params.isEmpty()) { - return baseURL; - } - StringBuilder url = new StringBuilder(baseURL); - url.append('?'); - for (Map.Entry> entry : params.entrySet()) { - Collection vals = entry.getValue(); - String key = entry.getKey(); - if (key == null || key.isBlank() || vals == null || vals.isEmpty()) { - continue; - } - for (String val : vals) { - url.append(URLEncoder.encode(entry.getKey(), UTF_8)); - url.append('='); - url.append(URLEncoder.encode(val, UTF_8)); - url.append('&'); - } - } - return url.substring(0, url.length() - 1); - } - - public static int getJavaMajorVersion() { - return interpretJavaMajorVersion(System.getProperty(SYSPROP_JAVA_VERSION)); - } - - /** - * Interprets String as a java version, returning the major version number. - * - * @param v the version string - * @return the major version number, or zero if unknown - */ - public static int interpretJavaMajorVersion(String v) { - try { - return Integer.parseInt(v.startsWith("1.") ? v.substring(2) : v); // NOI18N - } catch (NumberFormatException | NullPointerException ex) { - return 0; - } - } - - /** - * Provides the location of jre lib path, optionally the arch-dependent dir. The location - * depends on JDK version. - * - * @param graalPath graalVM installation root - * @param archDir if true, returns the arch-dependent path. - * @return jre lib dir - */ - public static Path getRuntimeLibDir(Path graalPath, boolean archDir) { - Path newLibPath; - Path base = getRuntimeBaseDir(graalPath); - switch (OS.get()) { - case LINUX: - Path temp = base.resolve(Paths.get("lib")); // NOI18N - if (!archDir || SystemUtils.getJavaMajorVersion() >= 10) { - newLibPath = temp; - } else { - newLibPath = temp.resolve(Paths.get(OS.sysName())); - } - break; - case MAC: - newLibPath = base.resolve(Paths.get("lib")); // NOI18N - break; - case WINDOWS: - newLibPath = base.resolve(Paths.get("bin")); // NOI18N - break; - case UNKNOWN: - default: - return null; - } - return newLibPath; - } - - /** - * Returns the JDK's runtime root dir. May be jre or ., depending on Java version - * - * @param jdkInstallDir installation path - * @return runtime path - */ - public static Path getRuntimeBaseDir(Path jdkInstallDir) { - int v = getJavaMajorVersion(); - if (v >= 10) { - return jdkInstallDir; - } else if (v > 0) { - return jdkInstallDir.resolve("jre"); // NOI18N - } - // use fallback: - Path jre = jdkInstallDir.resolve("jre"); // NOI18N - if (Files.exists(jre) && Files.isDirectory(jre)) { - return jre; - } else { - return jdkInstallDir; - } - } - - public static Path copySubtree(Path from, Path to) throws IOException { - Files.walkFileTree(from, new CopyDirVisitor(from, to)); - return to; - } - - public static class CopyDirVisitor extends SimpleFileVisitor { - - private Path fromPath; - private Path toPath; - private StandardCopyOption copyOption; - - public CopyDirVisitor(Path fromPath, Path toPath, StandardCopyOption copyOption) { - this.fromPath = fromPath; - this.toPath = toPath; - this.copyOption = copyOption; - } - - public CopyDirVisitor(Path fromPath, Path toPath) { - this(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING); - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) - throws IOException { - - Path targetPath = toPath.resolve(fromPath.relativize(dir)); - if (!Files.exists(targetPath)) { - Files.createDirectory(targetPath); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - - Files.copy(file, toPath.resolve(fromPath.relativize(file)), copyOption); - return FileVisitResult.CONTINUE; - } - } - - public static byte[] toHashBytes(String hashS) { - String val = hashS.trim(); - if (val.length() < 4) { - return null; - } - char c = val.charAt(2); - boolean divided = !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')); // NOI18N - boolean lenOK; - int s; - if (divided) { - lenOK = (val.length() + 1) % 3 == 0; - s = (val.length() + 1) / 3; - } else { - lenOK = (val.length()) % 2 == 0; - s = (val.length() + 1) / 2; - } - if (!lenOK) { - return null; - } - byte[] digest = new byte[s]; - int dI = 0; - for (int i = 0; i + 1 < val.length(); i += 2) { - int b; - try { - b = Integer.parseInt(val.substring(i, i + 2), 16); - } catch (NumberFormatException ex) { - return null; - } - if (b < 0) { - return null; - } - digest[dI++] = (byte) b; - if (divided) { - i++; - } - } - return digest; - } - - /** - * Formats a digest into a String representation. Prints digest bytes in hex, separates bytes by - * doublecolon. - * - * @param digest digest bytes - * @return Strign representation. - */ - public static String fingerPrint(byte[] digest) { - return fingerPrint(digest, true); - } - - /** - * Formats a digest into a String representation. Prints digest bytes in hex, separates bytes by - * doublecolon. - * - * @param digest digest bytes - * @param delimiter if true, put ':' between each two hex digits - * @return Strign representation. - */ - public static String fingerPrint(byte[] digest, boolean delimiter) { - if (digest == null) { - return null; - } - StringBuilder sb = new StringBuilder(digest.length * 3); - for (int i = 0; i < digest.length; i++) { - if (delimiter && i > 0) { - sb.append(':'); - } - sb.append(String.format("%02x", (digest[i] & 0xff))); - } - return sb.toString(); - } - - /** - * Hashes a string contents. - * - * @param s the input text - * @param delimiters use : delimiters in the fingerprint - * @return hex fingerprint of the input text - */ - public static String digestString(String s, boolean delimiters) { - try { - MessageDigest dg = MessageDigest.getInstance("SHA-256"); // NOI18N - dg.update(s.getBytes()); - byte[] digest = dg.digest(); - return SystemUtils.fingerPrint(digest, delimiters); - } catch (NoSuchAlgorithmException ex) { - throw new FailedOperationException(ex.getLocalizedMessage(), ex); - } - } - - public static String patternOsName(String os, String variant) { - if (os == null) { - return null; - } - String lc = os.toLowerCase(Locale.ENGLISH); - String suffix = ""; - if (variant != null && !variant.isEmpty()) { - suffix = "_" + variant.toLowerCase(Locale.ENGLISH); - } - switch (lc) { - case OS_MACOS_DARWIN: - case OS_TOKEN_MACOS: - return String.format("(:?%s%s|%s%s)", OS_MACOS_DARWIN, suffix, OS_TOKEN_MACOS, suffix); - default: - return lc + suffix; - } - } - - public static String patternOsArch(String arch) { - if (arch == null) { - return null; - } - String lc = arch.toLowerCase(Locale.ENGLISH); - switch (lc) { - case ARCH_AMD64: - case ARCH_X8664: - return "(:?" + ARCH_AMD64 + "|" + ARCH_X8664 + ")"; - default: - return lc; - } - } - - /** - * Normalizes architecture string. - * - * @param os OS name - * @param arch arch name - * @return normalized arch name, or {@code null}. - */ - public static String normalizeArchitecture(String os, String arch) { - if (arch == null) { - return null; - } - switch (arch.toLowerCase(Locale.ENGLISH)) { - case ARCH_X8664: - return ARCH_AMD64; - default: - return arch.toLowerCase(Locale.ENGLISH); - } - } - - /** - * Normalizes OS name string. - * - * @param os OS name - * @param arch arch name - * @return normalized os name, or {@code null}. - */ - public static String normalizeOSName(String os, String arch) { - if (os == null) { - return null; - } - switch (os.toLowerCase(Locale.ENGLISH)) { - case OS_MACOS_DARWIN: - return OS_TOKEN_MACOS; - default: - return os.toLowerCase(Locale.ENGLISH); - } - } - - /** - * Computes file digest. The default algorithm is SHA-256 - * - * @param localFile local file path - * @param digestAlgo the hash algorithm - * @return digest bytes - * @throws java.io.IOException in the case of I/O failure, or a digest failure/not found - */ - public static byte[] computeFileDigest(Path localFile, String digestAlgo) throws IOException { - try (SeekableByteChannel s = FileChannel.open(localFile, StandardOpenOption.READ)) { - ByteBuffer bb = ByteBuffer.allocate(4096); - long size = Files.size(localFile); - MessageDigest dg = MessageDigest.getInstance("SHA-256"); // NOI18N - while (size > 0) { - if (bb.limit() > size) { - bb.limit((int) size); - } - int r = s.read(bb); - if (r < 0) { - break; - } - bb.flip(); - dg.update(bb); - bb.clear(); - size -= r; - } - return dg.digest(); - } catch (NoSuchAlgorithmException ex) { - throw new IOException(ex); - } - } - - /** - * Determines if the path is a remote URL. If the passed string is not an absolute URL, attempts - * to interpret as relative path, which checks 'bad characters' and avoids paths that traverse - * above the root. Disallows absolute file:// URLs, URLs from file-based catalogs must be given - * as relative. - * - * @param pathOrURL path or URL to check. - * @return true, if the path is actually a URL. - */ - public static boolean isRemotePath(String pathOrURL) { - try { - URL u = toURL(pathOrURL); - String proto = u.getProtocol(); - if ("file".equals(proto)) { // NOI18N - throw new IllegalArgumentException("Absolute file:// URLs are not permitted."); - } else { - return true; - } - } catch (MalformedURLException ex) { - // expected - } - // will fail with an exception if the relative path contains bad chars or traverses up - fromCommonRelative(pathOrURL); - return false; - } - - /** - * Creates a {@link URI} from a string and converts it to a {@link URL}. Works around the - * deprecation of {@code new URL(String)} in Java 20. - * - * @param url the string to be parsed into a URL - * @return a url - * @throws MalformedURLException wrapper for thrown exceptions - */ - public static URL toURL(String url) throws MalformedURLException { - try { - return new URI(url).toURL(); - } catch (URISyntaxException | IllegalArgumentException ex) { - throw (MalformedURLException) new MalformedURLException().initCause(ex); - } - } - - /** - * Creates a {@link URI} from a first string, resolves the second string against it, and - * converts the result to a {@link URL}. Works around the deprecation of {@code new URL(String)} - * in Java 20. - * - * @param context the string to be parsed into a URL - * @param spec the string to be parsed into a URL in the context of {@code context} - * @return a url - * @throws MalformedURLException wrapper for thrown exceptions - */ - public static URL toURL(String context, String spec) throws MalformedURLException { - try { - return new URI(context).resolve(spec).toURL(); - } catch (URISyntaxException | IllegalArgumentException ex) { - throw (MalformedURLException) new MalformedURLException().initCause(ex); - } - } - - /** - * Converts the given {@link URL} to a {@link URI}, resolves the given string against it, and - * converts the result to a {@link URL}. Works around the deprecation of - * {@code new URL(URL, String)} in Java 20. - * - * @param context the URL to be converted to a URI - * @param spec the string to be resolved - * @return a url - * @throws MalformedURLException wrapper for thrown exceptions - */ - public static URL toURL(URL context, String spec) throws MalformedURLException { - try { - return context.toURI().resolve(spec).toURL(); - } catch (URISyntaxException | IllegalArgumentException ex) { - throw (MalformedURLException) new MalformedURLException().initCause(ex); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/URLConnectionFactory.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/URLConnectionFactory.java deleted file mode 100644 index ce3623c293d4..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/URLConnectionFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer; - -import java.io.IOException; -import java.net.URL; -import java.net.URLConnection; - -/** - * - * @author sdedic - */ -public interface URLConnectionFactory { - URLConnection createConnection(URL u, Configure configCallback) throws IOException; - - @FunctionalInterface - interface Configure { - void accept(URLConnection connection) throws IOException; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UnknownVersionException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UnknownVersionException.java deleted file mode 100644 index 6d36d2dfa5ce..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UnknownVersionException.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * - * @author sdedic - */ -public class UnknownVersionException extends InstallerStopException { - private static final long serialVersionUID = 33; - - private final transient Version version; - private final transient Version candidate; - - public UnknownVersionException(String s, Version v, Version c) { - super(s); - this.version = v; - this.candidate = c; - } - - public Version getCandidate() { - return candidate; - } - - public Version getVersion() { - return version; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UserAbortException.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UserAbortException.java deleted file mode 100644 index 5b00a5b81869..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/UserAbortException.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -/** - * - * @author sdedic - */ -public class UserAbortException extends InstallerStopException { - private static final long serialVersionUID = 1753L; - - public UserAbortException() { - super(null); - } - - public UserAbortException(Throwable cause) { - super(null, cause); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Version.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Version.java deleted file mode 100644 index e010b4e9b60d..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/Version.java +++ /dev/null @@ -1,740 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import java.util.function.Predicate; - -/** - * Version represents a component version. It has the form agreed for Graal product: - * {@code Year.Update.Patch.OneOffChange-release}. Pre-release versions (Year.UpdateX) have their - * Patch version set to 0; so for example 2020.0-0.beta.1 - *

- * "Installation" versions are versions with the same Year.Update.Patch-Release. Each Installation - * version will go to a separate directory. - * - * @author sdedic - */ -public final class Version implements Comparable { - /** - * Represents no version at all. All versions are greater than this one. - */ - public static final Version NO_VERSION = new Version("0.0.0.0", false); - private static final String WILDCARD = "*"; - - private final String versionString; - private final String normalizedString; - private final List releaseParts; - private final List versionParts; - - /** - * Contains wildcard. - */ - private final boolean wildcard; - - /** - * Entered by user, displayed 'as is'. - */ - private final boolean user; - - Version(String versionString, boolean fromUser) throws IllegalArgumentException { - this.versionString = versionString; - - boolean wc = false; - String normalized = fromUser ? versionString : SystemUtils.normalizeOldVersions(versionString); - List vp; - int releaseDash = normalized.indexOf('-'); - if (releaseDash == -1) { - if (fromUser) { - wc = true; - releaseParts = Collections.singletonList(WILDCARD); - } else { - releaseParts = Collections.emptyList(); - } - vp = parseParts(normalized); - } else { - String vS = normalized.substring(0, releaseDash); - String rS = normalized.substring(releaseDash + 1); - vp = parseParts(vS); - List rp = parseParts(rS); - if (fromUser && !rp.isEmpty()) { - String first = rp.get(0); - try { - Integer.parseInt(first); - } catch (NumberFormatException ex) { - // if (rp.size() > 1 && !Character.isDigit(rp.get(1).charAt(0))) { - rp.add(0, WILDCARD); - wc = true; - // } - } - rp.add(WILDCARD); - } - releaseParts = Collections.unmodifiableList(rp); - } - if (vp.size() < 2 || vp.size() > 4 || !Character.isDigit(vp.get(0).charAt(0)) || !Character.isDigit(vp.get(1).charAt(0))) { - throw new IllegalArgumentException("A format Year.Release[.Update[.Patch]] is required. Got: " + versionString); - } - // normalize all, not just releases, as releases are now "-1". - if (vp.size() < 4 && !isOldStyleVersion(vp.get(0))) { - vp = new ArrayList<>(vp); - while (vp.size() < 4) { - vp.add("0"); - } - this.normalizedString = print(vp, releaseParts); - } else { - normalizedString = normalized; - } - versionParts = vp; - wildcard = wc; - user = fromUser; - } - - static boolean isOldStyleVersion(String s) { - try { - // now mainly for ancient test data. PEDNING: update test data. - return Integer.parseInt(s) < 1; - } catch (NumberFormatException ex) { - // expected - return false; - } - } - - static String print(List vParts, List rParts) { - StringBuilder sb = new StringBuilder(); - for (String vp : vParts) { - if (sb.length() > 0) { - sb.append('.'); - } - sb.append(vp); - } - if (!rParts.isEmpty()) { - sb.append('-'); - boolean n = false; - for (String rp : rParts) { - if (n) { - sb.append('.'); - } - sb.append(rp); - n = true; - } - } - return sb.toString(); - } - - Version(String orig, List vParts, List rParts, boolean wc, boolean fromUser) { - this.versionParts = new ArrayList<>(vParts); - this.releaseParts = new ArrayList<>(rParts); - this.versionString = orig != null ? orig : print(vParts, rParts); - if (vParts.size() < 4 && isOldStyleVersion(vParts.get(0))) { - while (versionParts.size() < 4) { - versionParts.add("0"); - } - this.normalizedString = print(versionParts, releaseParts); - } else { - normalizedString = versionString; - } - wildcard = wc; - user = fromUser; - } - - /** - * Returns a Version variant, which can be compared to discover eligible updates. - * - * 1..0-0.beta.1 -> 1..0.x yes 1..0-0.beta.1 -> 1..0-0.rc.1 yes 1..0.0 -> 1..0.1 yes 1..0.0 -> - * 1..1.x no - * - * @return part of version which is the same for all updatable packages. - */ - public Version updatable() { - List vp = new ArrayList<>(versionParts); - vp.subList(3, vp.size()).clear(); - while (vp.size() < 3) { - vp.add("0"); - } - return new Version(null, vp, Collections.emptyList(), false, false); - } - - public Version onlyVersion() { - return new Version(null, versionParts, Collections.emptyList(), false, false); - } - - @Override - public int hashCode() { - int hash = 7; - hash = 43 * hash + Objects.hashCode(this.versionString); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - if (this == NO_VERSION || obj == NO_VERSION) { - // the other must be something else, sorry - return false; - } - final Version other = (Version) obj; - /* - * if (!Objects.equals(this.versionString, other.versionString)) { return false; } return - * true; - */ - return compareTo(other) == 0; - } - - @Override - public String toString() { - return normalizedString; - } - - public String originalString() { - return versionString; - } - - private static List parseParts(String s) throws IllegalArgumentException { - List parts = new ArrayList<>(); - final int l = s.length(); - boolean digit = false; - int lastP = -1; - - for (int i = 0; i < l; i++) { - char c = s.charAt(i); - if (!Character.isLetterOrDigit(c)) { - // separator - if (lastP >= 0) { - parts.add(s.substring(lastP, i)); - lastP = -1; - } - continue; - } - boolean nowDigit = Character.isDigit(c); - if (nowDigit != digit && lastP >= 0) { - parts.add(s.substring(lastP, i)); - lastP = i; - } else if (lastP < 0) { - lastP = i; - } - digit = nowDigit; - } - if (lastP >= 0) { - parts.add(s.substring(lastP)); - } - return parts; - } - - @Override - public int compareTo(Version o) { - if (o == this) { - return 0; - } else if (o == NO_VERSION) { - return 1; - } else if (this == NO_VERSION) { - return -1; - } else if (o == null) { - return 1; - } - int c = compareVersionParts(versionParts, o.versionParts, false); - if (c != 0) { - return c; - } - return compareVersionParts(releaseParts, o.releaseParts, true); - } - - private static int compareVersionParts(List pA, List pB, boolean release) { - Iterator iA = pA.iterator(); - Iterator iB = pB.iterator(); - int res = 0; - String sA = null; - String sB = null; - while ((res == 0) && iA.hasNext() && iB.hasNext()) { - sA = iA.next(); - sB = iB.next(); - res = compareVersionPart(sA, sB); - } - if (res != 0 || !(iA.hasNext() || iB.hasNext())) { - return res; - } - if (iA.hasNext()) { - if (release) { - /* - * if (WILDCARD.equals(iA.next()) || (WILDCARD.equals(sB))) { return 0; } - */ - if (WILDCARD.equals(iA.next()) && !iA.hasNext()) { - return 0; - } - if (WILDCARD.equals(sB)) { - return 0; - } - } - return 1; - } else if (iB.hasNext()) { - if (release) { - if (WILDCARD.equals(iB.next()) && !iB.hasNext()) { - return 0; - } - if (WILDCARD.equals(sA)) { - return 0; - } - // special case: if there's just one part and that one is zero, define it the same - if (pB.size() == 1 && "0".equals(pB.get(0))) { - return 0; - } - } - return -1; - } - throw new IllegalStateException("Should not happen"); // NOI18N - } - - /** - * Compares version parts, RPM-like rules. Acts like a {@link java.util.Comparator}. - * - * @param a first version - * @param b second version. - * @return less than 0, 0 or more than 0, as with Comparator. - */ - public static int compareVersionPart(String a, String b) { - if (WILDCARD.equals(a) || WILDCARD.equals(b)) { - return 0; - } - // handle of the parts == null - if (a == null) { - if (b != null) { - return -1; - } else { - return 0; - } - } else if (b == null) { - return 1; - } - boolean dA = Character.isDigit(a.charAt(0)); - boolean dB = Character.isDigit(a.charAt(0)); - if (dA != dB) { - // numeric part is always later - return dA ? 1 : -1; - } - if (dA && dB) { - int l = a.length() - b.length(); - if (l != 0) { - return l; - } - } - // if at this point dA == dB == true, all numbers have the same length, so we - // can use lexicographic comparison to numeric parts as well. - return a.compareTo(b); - } - - public boolean hasWildcard() { - return wildcard; - } - - public Version installVersion() { - List vps = new ArrayList<>(); - vps.add(versionParts.get(0)); - vps.add(versionParts.get(1)); - if (versionParts.size() > 2) { - vps.add(versionParts.get(2)); - } else { - vps.add("0"); - } - vps.add("0"); - return new Version(null, vps, releaseParts, wildcard, user); - } - - /** - * Produces a 'human readable' version. The intention is to hide complexities of prerelease - * versioning from the poor user. - * - * @return human-readable string. - */ - public String displayString() { - if (user) { - return originalString(); - } - StringBuilder sb = new StringBuilder(); - List vps = new ArrayList<>(versionParts); - if (vps.size() == 4 && "0".equals(vps.get(3))) { // NOI18N - vps.remove(3); - } - for (String vp : vps) { - if (sb.length() > 0) { - sb.append('.'); - } - sb.append(vp); - } - - if (releaseParts.isEmpty()) { - // no release part, no magic - return sb.toString(); - } - String firstRel = releaseParts.get(0); - List printedParts = new ArrayList<>(releaseParts); - try { - Integer.parseInt(firstRel); - printedParts.remove(0); - } catch (NumberFormatException ex) { - } - - if (printedParts.isEmpty()) { - return sb.toString(); - } - - boolean name = false; - boolean next = false; - int patchChar = -1; - sb.append("-"); - for (String s : printedParts) { - if (s.isEmpty() || WILDCARD.equals(s)) { // NOI18N - // skip artifical wildcards - continue; - } - if (Character.isDigit(s.charAt(0))) { - if (next && !name) { - sb.append("."); // NOI18N - } - if (name && patchChar != -1) { - sb.setCharAt(patchChar, '.'); // patch to .nameXX - } - sb.append(s); - name = false; - patchChar = -1; - } else { - patchChar = -1; - if (name) { - // was name, now is also name - sb.append("_"); // NOI18N - } else { - if (next) { - patchChar = sb.length(); - sb.append("-"); // NOI18N - } - } - sb.append(s); - - name = true; - } - next = true; - } - return sb.toString(); - } - - public Match match(Match.Type type) { - return new Match(this, type); - } - - /** - * Parses a new Version object. - * - * @param versionString the String specification of the version - * @return constructed Version object. - */ - public static Version fromString(String versionString) { - return versionString == null ? NO_VERSION : new Version(versionString, false); - } - - public static Version fromUserString(String userVersion) { - return userVersion == null ? NO_VERSION : new Version(userVersion, true); - } - - public static final String EXACT_VERSION = "="; // NOI18N - public static final String GREATER_VERSION = "+"; // NOI18N - public static final String COMPATIBLE_VERSION = "~"; // NOI18N - - /** - * Parses ID and optional version specification into ID and version selector. - * - * @param idSpec ID specification - * @param matchOut the version match - * @return id - */ - public static String idAndVersion(String idSpec, Version.Match[] matchOut) { - int eqIndex = idSpec.indexOf(EXACT_VERSION); - int moreIndex = idSpec.indexOf(GREATER_VERSION); - int compatibleIndex = idSpec.indexOf(COMPATIBLE_VERSION); - int i = -1; - Version.Match.Type type = null; - - if (eqIndex > 0) { - type = Match.Type.EXACT; - i = eqIndex; - } else if (moreIndex > 0) { - type = Match.Type.INSTALLABLE; - i = moreIndex; - } else if (compatibleIndex > 0) { - type = Match.Type.COMPATIBLE; - i = compatibleIndex; - } else { - matchOut[0] = Version.NO_VERSION.match(Match.Type.MOSTRECENT); - return idSpec; - } - matchOut[0] = Version.fromUserString(idSpec.substring(i + 1)).match(type); - return idSpec.substring(0, i); - } - - /** - * Accepts version specification and creates a version filter. - *

- * Version-input must start with "+", "~", "=" or a digit. Non-version inputs will produce - * {@code null}. - *

- *
    - *
  • =version means exactly the version specified ({@link Match.Type#EXACT}) - *
  • +version means the specified version, or above ({@link Match.Type#INSTALLABLE}) - *
  • ~version or version means that version or greater, but within a release range ( - * {@link Match.Type#COMPATIBLE} - *
- * - * @param spec - * @return version match or {@code null}. - */ - public static Version.Match versionFilter(String spec) { - if (spec == null || spec.isEmpty()) { - return null; - } - - int eqIndex = spec.indexOf(EXACT_VERSION); - int moreIndex = spec.indexOf(GREATER_VERSION); - int compatibleIndex = spec.indexOf(COMPATIBLE_VERSION); - int i = -1; - Version.Match.Type type = null; - - if (eqIndex >= 0) { - type = Match.Type.EXACT; - i = eqIndex; - } else if (moreIndex >= 0) { - type = Match.Type.INSTALLABLE; - i = moreIndex; - } else if (compatibleIndex >= 0) { - type = Match.Type.COMPATIBLE; - i = compatibleIndex; - } else { - if (Character.isDigit(spec.charAt(0))) { - return Version.fromString(spec).match(Match.Type.COMPATIBLE); - } else { - return null; - } - } - return Version.fromString(spec.substring(i + 1)).match(type); - } - - public static final class Match implements Predicate { - public enum Type { - /** - * The exact version number. - */ - EXACT, - - /** - * Versions greater or equal than the one defined. - */ - INSTALLABLE, - - /** - * Also greater, but also indicates the most recent one is needed. - */ - MOSTRECENT, - - /** - * Versions compatible. For version r.x.y.z, all versions with the same r.x.y are - * compatible. - */ - COMPATIBLE, - - /** - * Version which is equal or greater. - */ - GREATER, - - /** - * Dependency check. Reverse of {@link #INSTALLABLE}, accepts future versions. - */ - SATISFIES, - - /** - * Dependency check. The tested install version must be the same, and the patchlevel - * must be lower or equal. - */ - SATISFIES_COMPATIBLE, - } - - private final Type matchType; - private final Version version; - - Match(Version version, Type matchType) { - this.matchType = matchType; - this.version = version; - } - - @Override - public boolean test(Version t) { - if (t == null) { - return matchType != Type.EXACT; - } - switch (matchType) { - case EXACT: - return version.equals(t); - - case GREATER: - return version.compareTo(t) <= 0; - - case INSTALLABLE: - return version.installVersion().compareTo(t.installVersion()) <= 0; - - case MOSTRECENT: - throw new IllegalArgumentException(); - - case COMPATIBLE: - return version.installVersion().equals(t.installVersion()); - - case SATISFIES_COMPATIBLE: { - int a = version.installVersion().compareTo(t.installVersion()); - if (a != 0) { - return false; - } - return version.onlyVersion().compareTo(t.onlyVersion()) >= 0; - } - - case SATISFIES: { - int a = version.installVersion().compareTo(t.installVersion()); - if (a < 0) { - return true; - } - return version.onlyVersion().compareTo(t.onlyVersion()) >= 0; - } - } - return false; - } - - public Version getVersion() { - return version; - } - - public Type getType() { - return matchType; - } - - @Override - public String toString() { - return matchType.toString() + "[" + version + "]"; - } - - /** - * Attempts to turn a wildcard version match into normal one. - * - * @param allVersions all versions to select from - * @return resolved match, or match that will produce an error on test. - */ - public Match resolveWildcards(Collection allVersions, Feedback fb) { - if (!version.hasWildcard()) { - return this; - } - List ordered = new ArrayList<>(allVersions); - Collections.sort(ordered); - Version candidate = null; - switch (matchType) { - case MOSTRECENT: - throw new IllegalArgumentException(); - - case EXACT: - // exact: find a matching version, - // if not found return the suppressed wildcard one for reporting - for (Version v : ordered) { - if (v.compareTo(version) == 0) { - if (candidate != null) { - // should not really happen - throw new IllegalArgumentException(); - } - candidate = v; - } - } - if (candidate == null) { - return this; - } else { - return new Match(candidate, matchType); - } - - case SATISFIES: - case SATISFIES_COMPATIBLE: - case INSTALLABLE: - case GREATER: - // the lowest possible matching version - // exact: find a matching version, - // if not found return the suppressed wildcard one for reporting - for (Version v : ordered) { - if (v.compareTo(version) >= 0) { - candidate = v; - break; - } - } - if (candidate == null) { - return this; - } else { - return new Match(candidate, matchType); - } - - case COMPATIBLE: - Version myInst = version.installVersion(); - Version myBase = myInst.onlyVersion(); - Version report = null; - for (Version v : ordered) { - Version inst = v.installVersion(); - if (myInst.equals(inst)) { - candidate = v; - } - if (myBase.equals(inst.onlyVersion())) { - report = v; - } - } - if (candidate == null) { - String msg; - if (report == null) { - msg = fb.withBundle(Version.class).l10n( - "VERSION_UnknownVersion1", version.displayString(), null); - } else { - msg = fb.withBundle(Version.class).l10n( - "VERSION_UnknownVersion2", version.displayString(), report.displayString()); - } - throw new UnknownVersionException( - msg, - version, report); - } else { - return new Match(candidate, matchType); - } - default: - throw new IllegalStateException(); - } - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/Bundle.properties deleted file mode 100644 index b9e9867e1d52..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/Bundle.properties +++ /dev/null @@ -1,23 +0,0 @@ -REMOTE_CatalogLabel=Component catalog for {0} -REMOTE_CatalogLabel2=Component catalog -REMOTE_ErrorDownloadCatalogNotFound=The component catalog was not found at {0}. -REMOTE_WarningErrorDownloadCatalogNotFoundSkip=Warning: The component catalog was not found at {0}. Skipping. -REMOTE_ErrorDownloadCatalog=Error downloading component catalog from {0}: {1}. \n\ - Please check your connection and proxy settings. \ - If your machine is behind a proxy, you must set your environment variables (http_proxy, https_proxy, ...) appropriately. -REMOTE_ErrorDownloadCatalogProxy=Component catalog is unreachable. \n\ - Please check your connection and proxy settings. \ - If your machine is behind a proxy, you must set your environment variables (http_proxy, https_proxy, ...) appropriately. -REMOTE_CorruptedCatalogFile=Catalog file {0} is corrupted. -REMOTE_ComponentFileLabel=Component {0} -REMOTE_UnsupportedGraalVersion=Unsupported GraalVM version: {0}, platform {1}/{2} -REMOTE_ErrorDownloadingComponent=Error downloading component {0} from {1}: {2} -REMOTE_ErrorDownloadingNotExist=Package for component {0} is not accessible at {1} -REMOTE_InvalidURL={0} is not a valid catalog URL: {1} -REMOTE_GenericLocalFile=Local file -REMOTE_LocalFileCatalog={0} -REMOTE_ErrorClosingJarFile=Could not close archive file {0}: {1} -REMOTE_CatalogDoesNotContainComponents=Catalog {0} does not contain any components. - -# {0} - original error message. -ERR_ClosingJarFile=Error closing jar file: {0} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/JarPackageProvider.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/JarPackageProvider.java deleted file mode 100644 index 2a9070fbf8fc..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/JarPackageProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.ce; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.jar.JarFile; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.jar.JarMetaLoader; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.ComponentArchiveReader; - -/** - * Loads JAR files. - * - * @author sdedic - */ -public final class JarPackageProvider implements ComponentArchiveReader { - @Override - public MetadataLoader createLoader(Path p, byte[] magic, String serial, Feedback feedback, boolean verify) throws IOException { - if ((magic[0] == 0x50) && (magic[1] == 0x4b) && - (magic[2] == 0x03) && (magic[3] == 0x04)) { - JarFile jf = new JarFile(p.toFile(), verify); - boolean ok = false; - try { - JarMetaLoader ldr = new JarMetaLoader(jf, serial, feedback); - ok = true; - return ldr; - } finally { - if (!ok) { - try { - jf.close(); - } catch (IOException ex) { - feedback.error("ERR_ClosingJarFile", ex, ex.getLocalizedMessage()); - } - } - } - } else { - return null; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/WebCatalog.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/WebCatalog.java deleted file mode 100644 index 589314bf9970..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/ce/WebCatalog.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.ce; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.ConnectException; -import java.net.MalformedURLException; -import java.net.NoRouteToHostException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.model.RemoteInfoProcessor; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.remote.RemotePropertiesStorage; - -public class WebCatalog implements SoftwareChannel { - private final String urlString; - private final SoftwareChannelSource source; - - private URL catalogURL; - private Feedback feedback; - private ComponentRegistry local; - private ComponentStorage storage; - private RuntimeException savedException; - private RemoteInfoProcessor remoteProcessor = RemoteInfoProcessor.NONE; - - /** - * The accepted version - only exact match is supported at the moment. - */ - private Version.Match matchVersion; - - /** - * If true, enables loading different versions from V1 catalogs. - */ - private boolean enableV1Versions; - - public WebCatalog(String u, SoftwareChannelSource source) { - this.urlString = u; - this.source = source; - } - - public RemoteInfoProcessor getRemoteProcessor() { - return remoteProcessor; - } - - public void setRemoteProcessor(RemoteInfoProcessor remoteProcessor) { - this.remoteProcessor = remoteProcessor; - } - - public Version.Match getMatchVersion() { - return matchVersion; - } - - public boolean isEnableV1Versions() { - return enableV1Versions; - } - - /** - * Enables version processing in V1 catalogs. Note that not complete version string semantics is - * possible with v1 format, as version may contain underscores (_), which are delimiters in v1 - * catalogs. - *

- * The default setting is false. - * - * @param enableV1Versions true, if should be enabled. - */ - public void setEnableV1Versions(boolean enableV1Versions) { - this.enableV1Versions = enableV1Versions; - } - - /** - * Overrides versions loaded by this catalog. By default own version only is accepted. If - * matchVersion is set, the catalog will load matching version(s). At this moment only exact - * match is supported. - * - * @param aMatchVersion - */ - public void setMatchVersion(Version.Match aMatchVersion) { - this.matchVersion = aMatchVersion; - } - - protected static boolean acceptURLScheme(String scheme, String urlSpec) { - switch (scheme) { - case "http": // NOI18N - case "https": // NOI18N - case "ftp": // NOI18N - case "ftps": // NOI18N - return true; - case "file": // NOI18N - // accept only regular files - try { - Path p = new File(new URI(urlSpec)).toPath(); - return Files.isRegularFile(p) && Files.isReadable(p); - } catch (URISyntaxException ex) { - // cannot be converted to file, bail out - break; - } - } - return false; - } - - public void init(CommandInput in, Feedback out) { - init(in.getLocalRegistry(), out); - } - - public void init(ComponentRegistry aLocal, Feedback out) { - this.feedback = out.withBundle(WebCatalog.class); - this.local = aLocal; - } - - @Override - public ComponentStorage getStorage() { - if (this.storage != null) { - return this.storage; - } - - Map graalCaps = local.getGraalCapabilities(); - - StringBuilder sb = new StringBuilder(); - sb.append( - SystemUtils.patternOsName( - graalCaps.get(CommonConstants.CAP_OS_NAME), - graalCaps.get(CommonConstants.CAP_OS_VARIANT)).toLowerCase()); - sb.append("_"); - sb.append(SystemUtils.patternOsArch(graalCaps.get(CommonConstants.CAP_OS_ARCH).toLowerCase())); - - try { - catalogURL = SystemUtils.toURL(urlString); - } catch (MalformedURLException ex) { - throw feedback.failure("REMOTE_InvalidURL", ex, catalogURL, ex.getLocalizedMessage()); - } - - Properties props = new Properties(); - // create the storage. If the init fails, but process will not terminate, the storage will - // serve no components on the next call. - RemotePropertiesStorage newStorage = createPropertiesStorage(feedback, local, props, sb.toString(), catalogURL); - if (remoteProcessor != null) { - newStorage.setRemoteProcessor(remoteProcessor); - } - Properties loadProps = new Properties(); - FileDownloader dn; - try { - // avoid duplicate (failed) downloads - if (savedException != null) { - throw savedException; - } - catalogURL = SystemUtils.toURL(urlString); - String l = source.getLabel(); - dn = new FileDownloader(feedback.l10n(l == null || l.isEmpty() ? "REMOTE_CatalogLabel2" : "REMOTE_CatalogLabel", l), catalogURL, feedback); - dn.download(); - } catch (NoRouteToHostException | ConnectException ex) { - throw savedException = feedback.failure("REMOTE_ErrorDownloadCatalogProxy", ex, catalogURL, ex.getLocalizedMessage()); - } catch (FileNotFoundException ex) { - // treat missing resources as non-fatal errors, print warning - feedback.error("REMOTE_WarningErrorDownloadCatalogNotFoundSkip", ex, catalogURL); - this.storage = newStorage; - return storage; - } catch (IOException ex) { - throw savedException = feedback.failure("REMOTE_ErrorDownloadCatalog", ex, catalogURL, ex.getLocalizedMessage()); - } - // download is successful; if the processing fails after download, next call will report an - // empty catalog. - this.storage = newStorage; - - StringBuilder oldGraalPref = new StringBuilder("^" + BundleConstants.GRAAL_COMPONENT_ID); - oldGraalPref.append('.'); - - String graalVersionString; - Version normalizedVersion; - - if (matchVersion != null) { - graalVersionString = matchVersion.getVersion().displayString(); - normalizedVersion = matchVersion.getVersion().installVersion(); - } else { - // read from the release file - graalVersionString = graalCaps.get(CommonConstants.CAP_GRAALVM_VERSION).toLowerCase(); - normalizedVersion = local.getGraalVersion().installVersion(); - } - - StringBuilder graalPref = new StringBuilder(oldGraalPref); - - oldGraalPref.append(Pattern.quote(graalVersionString)); - - oldGraalPref.append('_').append(sb); - graalPref.append(sb).append('/'); - graalPref.append("(?[^/]+)$"); // NOI18N - - try (FileInputStream fis = new FileInputStream(dn.getLocalFile())) { - loadProps.load(fis); - } catch (IllegalArgumentException | IOException ex) { - throw feedback.failure("REMOTE_CorruptedCatalogFile", ex, catalogURL); - } - - Pattern oldPrefixPattern = Pattern.compile(oldGraalPref.toString(), Pattern.CASE_INSENSITIVE); - Pattern newPrefixPattern = Pattern.compile(graalPref.toString(), Pattern.CASE_INSENSITIVE); - Stream propNames = loadProps.stringPropertyNames().stream(); - boolean foundPrefix = propNames.anyMatch(p -> { - if (oldPrefixPattern.matcher(p).matches()) { - return true; - } - Matcher m = newPrefixPattern.matcher(p); - if (!m.find() || m.start() > 0) { - return false; - } - try { - Version v = Version.fromString(m.group("ver")); // NOI18N - return normalizedVersion.match(Version.Match.Type.INSTALLABLE).test(v); - } catch (IllegalArgumentException ex) { - return false; - } - }); - if (!foundPrefix) { - boolean graalPrefixFound = false; - boolean componentFound = false; - for (String s : loadProps.stringPropertyNames()) { - if (s.startsWith(BundleConstants.GRAAL_COMPONENT_ID)) { - graalPrefixFound = true; - } - if (s.startsWith("Component.")) { - componentFound = true; - } - } - if (!componentFound) { - // no graal prefix, no components - feedback.verboseOutput("REMOTE_CatalogDoesNotContainComponents", catalogURL); - return newStorage; - } else if (!graalPrefixFound) { - // strange thing, no graal declaration, but components are there ? - throw feedback.failure("REMOTE_CorruptedCatalogFile", null, catalogURL); - } else { - throw new IncompatibleException( - feedback.l10n("REMOTE_UnsupportedGraalVersion", - graalCaps.get(CommonConstants.CAP_GRAALVM_VERSION), - graalCaps.get(CommonConstants.CAP_OS_NAME), - graalCaps.get(CommonConstants.CAP_OS_ARCH)), - null); - } - } - props.putAll(loadProps); - return newStorage; - } - - protected RemotePropertiesStorage createPropertiesStorage(Feedback aFeedback, - ComponentRegistry aLocal, Properties props, String selector, URL baseURL) { - return new RemotePropertiesStorage( - aFeedback, aLocal, props, selector, null, baseURL); - } - - @Override - public FileDownloader configureDownloader(ComponentInfo cInfo, FileDownloader dn) { - return dn; - } - - public static class WebCatalogFactory implements SoftwareChannel.Factory { - private CommandInput input; - - @Override - public SoftwareChannel createChannel(SoftwareChannelSource src, CommandInput in, Feedback fb) { - String urlSpec = src.getLocationURL(); - int schColon = urlSpec.indexOf(':'); // NOI18N - if (schColon == -1) { - return null; - } - String scheme = urlSpec.toLowerCase().substring(0, schColon); - if (acceptURLScheme(scheme, urlSpec)) { - WebCatalog c = new WebCatalog(urlSpec, src); - c.init(in, fb); - return c; - } - return null; - } - - @Override - public void init(CommandInput in, Feedback out) { - assert this.input == null; - this.input = in; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AbstractInstaller.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AbstractInstaller.java deleted file mode 100644 index 23a03ef7ada9..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AbstractInstaller.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.Closeable; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.Verifier; - -/** - * Abstract configurable base for installer. The real installer and test stub inherits from this - * base; are configured by InstallCommand. - * - * @author sdedic - */ -public abstract class AbstractInstaller implements Closeable { - protected final Feedback feedback; - protected final ComponentInfo componentInfo; - protected final ComponentRegistry registry; - protected final ComponentCollection catalog; - protected final Archive archive; - protected final FileOperations fileOps; - - private Map permissions = Collections.emptyMap(); - private Map symlinks = Collections.emptyMap(); - private Set componentDirectories = Collections.emptySet(); - private final Set trackedPaths = new HashSet<>(); - private Path licenseRelativePath; - private boolean replaceDiferentFiles; - private boolean replaceComponents; - private boolean dryRun; - private boolean ignoreRequirements; - private boolean failOnExisting = true; - private Path installPath; - private boolean allowUpgrades; - - public AbstractInstaller(Feedback fb, FileOperations fops, ComponentInfo info, - ComponentRegistry reg, ComponentCollection cat, Archive a) { - this.feedback = fb; - this.componentInfo = info; - this.registry = reg; - this.archive = a; - this.catalog = cat; - this.fileOps = fops; - } - - public Archive getArchive() { - return archive; - } - - public boolean isComplete() { - return archive != null; - } - - public boolean isAllowUpgrades() { - return allowUpgrades; - } - - public void setAllowUpgrades(boolean allowUpgrades) { - this.allowUpgrades = allowUpgrades; - } - - public boolean isFailOnExisting() { - return failOnExisting; - } - - public void setFailOnExisting(boolean failOnExisting) { - this.failOnExisting = failOnExisting; - } - - public boolean isReplaceDiferentFiles() { - return replaceDiferentFiles; - } - - public void setReplaceDiferentFiles(boolean replaceDiferentFiles) { - this.replaceDiferentFiles = replaceDiferentFiles; - } - - public boolean isReplaceComponents() { - return replaceComponents; - } - - public void setReplaceComponents(boolean replaceComponents) { - this.replaceComponents = replaceComponents; - } - - public boolean isIgnoreRequirements() { - return ignoreRequirements; - } - - public void setIgnoreRequirements(boolean ignoreRequirements) { - this.ignoreRequirements = ignoreRequirements; - } - - public ComponentInfo getComponentInfo() { - return componentInfo; - } - - public Set getTrackedPaths() { - return trackedPaths; - } - - public Map getPermissions() { - return permissions; - } - - public void setPermissions(Map permissions) { - this.permissions = permissions; - } - - public Map getSymlinks() { - return symlinks; - } - - public void setSymlinks(Map symlinks) { - this.symlinks = symlinks; - } - - public abstract void revertInstall(); - - public Verifier createVerifier() { - return new Verifier(feedback, registry, catalog) - .ignoreRequirements(ignoreRequirements) - .replaceComponents(replaceComponents) - .ignoreExisting(!failOnExisting); - } - - public Verifier validateRequirements() { - Verifier vrf = createVerifier(); - return vrf.setVersionMatch(registry.getGraalVersion().match(Version.Match.Type.COMPATIBLE)) - .validateRequirements(componentInfo); - } - - /** - * Validates requirements, decides whether to install. Returns false if the component should be - * skipped. - * - * @return true, if the component should be installed - * @throws IOException - */ - public abstract boolean validateAll() throws IOException; - - public abstract void validateFiles() throws IOException; - - public abstract void validateSymlinks() throws IOException; - - public abstract void processPermissions() throws IOException; - - public abstract void createSymlinks() throws IOException; - - public Path getInstallPath() { - return installPath; - } - - public void setInstallPath(Path installPath) { - this.installPath = installPath.normalize(); - } - - public Path getLicenseRelativePath() { - return licenseRelativePath; - } - - public void setLicenseRelativePath(Path licenseRelativePath) { - this.licenseRelativePath = licenseRelativePath; - } - - @Override - public void close() throws IOException { - if (archive != null) { - archive.close(); - } - } - - public boolean isDryRun() { - return dryRun; - } - - public void setDryRun(boolean dryRun) { - this.dryRun = dryRun; - } - - public Set getComponentDirectories() { - return componentDirectories; - } - - public void setComponentDirectories(Set componentDirectories) { - this.componentDirectories = componentDirectories; - } - - protected void addTrackedPath(String path) { - trackedPaths.add(path); - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AvailableCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AvailableCommand.java deleted file mode 100644 index 8c908eef0dd5..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/AvailableCommand.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.Verifier; - -/** - * - * @author sdedic - */ -public class AvailableCommand extends ListInstalledCommand { - - private Version.Match vmatch; - - @Override - public Map supportedOptions() { - Map opts = new HashMap<>(super.supportedOptions()); - opts.put(Commands.OPTION_ALL, ""); - opts.put(Commands.LONG_OPTION_ALL, Commands.OPTION_ALL); - opts.put(Commands.OPTION_VERSION, "s"); - opts.put(Commands.LONG_OPTION_VERSION, Commands.OPTION_VERSION); - - opts.put(Commands.OPTION_CATALOG, "X"); - opts.put(Commands.OPTION_FOREIGN_CATALOG, "s"); - opts.put(Commands.LONG_OPTION_FOREIGN_CATALOG, Commands.OPTION_FOREIGN_CATALOG); - - opts.put(Commands.OPTION_USE_EDITION, "s"); - opts.put(Commands.LONG_OPTION_USE_EDITION, Commands.OPTION_USE_EDITION); - - opts.put(Commands.OPTION_SHOW_CORE, ""); - opts.put(Commands.LONG_OPTION_SHOW_CORE, Commands.OPTION_SHOW_CORE); - - opts.put(Commands.OPTION_SHOW_UPDATES, ""); - opts.put(Commands.LONG_OPTION_SHOW_UPDATES, Commands.OPTION_SHOW_UPDATES); - return opts; - } - - @Override - protected ComponentCollection initRegistry() { - super.initRegistry(); - if (showUpdates) { - input.getRegistry().setAllowDistUpdate(true); - } - return input.getRegistry(); - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - String v = commandInput.optValue(Commands.OPTION_VERSION); - if (v != null) { - vmatch = Version.versionFilter(v); - } - showUpdates = commandInput.hasOption(Commands.OPTION_SHOW_UPDATES) || commandInput.hasOption(Commands.OPTION_ALL); - showCore = commandInput.hasOption(Commands.OPTION_SHOW_CORE) | showUpdates | commandInput.hasOption(Commands.OPTION_USE_EDITION); - super.init(commandInput, feedBack); - } - - private boolean showUpdates; - private boolean showCore; - - @Override - public int execute() throws IOException { - if (input.optValue(Commands.OPTION_HELP) != null) { - feedback.output("AVAILABLE_Help"); - return 0; - } - return super.execute(); - } - - private boolean defaultFilter = true; - - @Override - protected List filterDisplayedVersions(String id, Collection infos) { - if (input.optValue(Commands.OPTION_ALL) != null) { - return super.filterDisplayedVersions(id, infos); - } - Set seen = new HashSet<>(); - Collection filtered = new ArrayList<>(); - - Verifier vrf = new Verifier(feedback, input.getLocalRegistry(), input.getRegistry()); - vrf.setCollectErrors(true); - vrf.setSilent(true); - vrf.ignoreExisting(true); - if (showUpdates) { - vrf.setVersionMatch(getRegistry().getGraalVersion().match(Version.Match.Type.INSTALLABLE)); - } else { - vrf.setVersionMatch(getRegistry().getGraalVersion().match(Version.Match.Type.SATISFIES_COMPATIBLE)); - } - if (defaultFilter) { - List sorted = new ArrayList<>(infos); - Collections.sort(sorted, ComponentInfo.versionComparator().reversed()); - for (ComponentInfo ci : sorted) { - // for non-core components, only display those compatible with the current release. - if (vrf.validateRequirements(ci).hasErrors()) { - continue; - } - if (CommonConstants.GRAALVM_CORE_PREFIX.equals(ci.getId())) { - if (!showCore || - // graalvm core does not depend on anything: - !vrf.getVersionMatch().test(ci.getVersion())) { - // filter out graalvm core by default - continue; - } - } - // select just the most recent version - filtered.add(ci); - break; - } - } else { - for (ComponentInfo ci : infos) { - if (seen.add(ci.getVersion().installVersion())) { - filtered.add(ci); - } - } - } - return super.filterDisplayedVersions(id, filtered); - } - - @Override - protected String acceptExpression(String expr) { - if (vmatch != null) { - return super.acceptExpression(expr); - } - Version.Match vm = Version.versionFilter(expr); - if (vm == null) { - vmatch = getRegistry().getGraalVersion().match(Version.Match.Type.INSTALLABLE); - defaultFilter = true; - return expr; - } else { - defaultFilter = false; - vmatch = vm; - // consume - return null; - } - } - - @Override - protected Version.Match getVersionFilter() { - return vmatch == null ? super.getVersionFilter() : vmatch; - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Bundle.properties deleted file mode 100644 index 0d5ccfe118ab..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Bundle.properties +++ /dev/null @@ -1,409 +0,0 @@ -INSTALL_FileManipulationError=I/O error encountered during processing component {0}: {1} -INSTALL_OverwriteWithDirectory=Refused to overwrite file with directory: {0} -INSTALL_OverwriteWithFile=Refused to overwrite directory with file: {0} -INSTALL_OverwriteWithLink=Refused to overwrite directory or file with symlink: {0} -INSTALL_ReplacedFileDiffers=Existing file contents differ: {0}. Run with -f to force overwrite. -INSTALL_CannotCleanupFile=Could not clean up file {0}: {1} -INSTALL_ErrorClosingFile=Error closing component file {0}: {1} -INSTALL_SkipIdenticalFile=Skipping identical file: {0} -INSTALL_InstallingFile=Extracting: {0} -INSTALL_ReplacingFile=Replacing: {0} -INSTALL_CreatingDirectory=Creating directory: {0} -INSTALL_CreatingSymlink=Creating symbolic link: {0} -> {1} -INSTALL_CleanupFile=Cleaning up file: {0} -INSTALL_CleanupDirectory=Cleaning up directory: {0} -INSTALL_SkippingSharedFile=Skipping shared file: {0} -INSTALL_FailedToDeleteFile=Failed to remove file {0}: {1} -INSTALL_FailedToDeleteDirectory=Failed to remove directory {0}: {1} -INSTALL_PrepareToInstall=Preparing to install {0}, contains {1}, version {2} ({1}) -INSTALL_ErrorDuringProcessing=Installation of {0} failed: {1} -INSTALL_IgnoreFailedInstallation=Ignored failure: {0} -INSTALL_IgnoreFailedInstallation2=Ignored failed installation of {0}: {1} -INSTALL_VerboseValidation=Checking entry: {0} -INSTALL_VerboseCapabilityNone=None -INSTALL_VerboseCheckRequirements=Checking requirements of component {1} ({0}), version {2} -INSTALL_VerboseCapability=\tRequires {0} = {1}, GraalVM provides: {2} -INSTALL_VerboseProcessingArchive=Processing Component archive: {0} -INSTALL_VerboseProcessingComponent=Processing Component: {0} -INSTALL_InvalidComponentArchive={0} is corrupted or is not a component archive. -INSTALL_RemoveExistingComponent=Replacing existing component: {1} ({0}, version {2}) with {4} ({3}, version {5}) -INSTALL_InstallNewComponent=Installing new component: {1} ({0}, version {2}) -UNINSTALL_DeletingDirectoryRecursively=Erasing subtree: {0} -INSTALL_ComponentAlreadyInstalled=Component {0} ({1}) is already installed. - -INSTALL_WriteOutsideGraalvm=Attempt to write outside GraalVM directory: {0} -INSTALL_SymlinkOutsideGraalvm=Symlink {0} points outside GraalVM directory: {1} - -INSTALLER_FailError={0} - -UNINSTALL_UnknownComponentId=Unknown component id: {0}. Use "gu list" to retrieve the list of components and their IDs. -UNINSTALL_IgnoreFailed=Failed uninstallation of {0} ignored. The error was: {1} -UNINSTALL_ErrorDuringProcessing=Uninstallation failed: {0} -UNINSTALL_UninstallingComponent=Uninstalling: {0} -UNINSTALL_DeletingFile=Deleting: {0} -UNINSTALL_DeletingDirectory=Deleting directory: {0} -UNINSTALL_ErrorRestoringPermissions=Error restoring permissions for {0}: {1} -UNINSTALL_BrokenDependenciesWarn=Warning: Uninstallation will break dependent components: -UNINSTALL_BrokenDependencies=Uninstallation would break dependent components. Broken dependencies follow: -UNINSTALL_BreakDepSource={0} ({1}) is required by: -UNINSTALL_BreakDepTarget=\ {0} ({1}) -UNINSTALL_BreakDependenciesTerminate=Other components would be broken by this operation; will terminate. Use -D or -f to override. -UNINSTALL_BrokenDependenciesRemove=Uninstallation would break dependent Components. They will be uninstalled as well: - -INSTALL_ParametersMissing=Missing filename(s) of component bundle(s) to install. -INSTALL_Help=\ - Usage:\n\ - gu install [-0cCDfFiLMnorsuvxyY] param [param ...]\n\ -\n\ -Options:\n\ -\ -0, --dry-run dry run, make no changes\n\ -\ -c, --catalog treat parameters as component IDs from a catalog of GraalVM components. This is the default.\n\ -\ -C, --custom-catalog use a specific catalog URL or local directory to locate components.\n\ -\ -D, --local-deps attempt to resolve dependencies using local files located next to the paths on the command line.\n\ -\ --edition use catalogs from the specified edition\n\ -\ -f, --force force overwrite, bypass version checks.\n\ -\ -i, --fail-existing fail on existing component.\n\ -\ -L, --local-file, --file treat parameters as local filenames of packaged components.\n\ -\ -M, --no-deps ignore dependencies.\n\ -\ -n, --no-progress do not display download progress.\n\ -\ -o, --overwrite overwrite different files.\n\ -\ -r, --replace replace existing components.\n\ -\ -s, --no-verify-jars skip integrity verification of component archives\n\ -\ -u, --url interpret parameters as URLs of packaged components.\n\ -\ -v, --verbose be verbose. Print versions and dependency information.\n\ -\ -x, --ignore ignore failures.\n\ -\ -y, --only-validate do not install, just check compatibility and conflicting files.\n\ -\ -Y, --validate-before download, verify, check file conflict before any disk change is made.\n - - -UNINSTALL_ParametersMissing=Missing component ID(s) to uninstall. -UNINSTALL_Help=\ - Usage:\n\ - gu remove [-0DfMxv] id [id ...]\n\ -\n\ -Options:\n\ -\ -0, --dry-run dry run, make no changes.\n\ -\ -D, --remove-deps remove dependent components as well.\n\ -\ -f, --force force overwrite, bypass version checks.\n\ -\ -M, --no-deps ignore dependencies.\n\ -\ -v, --verbose be verbose. Print versions and dependency information.\n\ -\ -x, --ignore do not stop on undeletable files.\n\ - -LIST_NoComponentsFound=No components found. -LIST_ComponentShortListHeader=\ -ComponentId Version Component name Stability Origin \n\ ---------------------------------------------------------------------------------------------------------------------------------- -# 25 +20 +30 +30 -# The following bundle is actually a String.format format pattern. -# The most important is the width and precision which should follow the header widths -LIST_ComponentShortListHeader_Simple@=*ComponentList -LIST_ComponentShortList=%1$-25.25s%2$-20.20s%3$-30.30s%6$-30.30s%4$s -LIST_ComponentShortList_Simple@=%5$s;%2$s;%3$s;%4$s;%6$s;%7$s -LIST_PrintVerbatim={0} -LIST_ComponentFilesHeader={0} installed files and directories: -LIST_ComponentFilesHeader_Simple@=*Files:{0} -LIST_ComponentFilesEnd@=*EndFiles -LIST_MetadataUnknown=n/a -LIST_ComponentBasicInfo=\ -ID : {0}\n\ -Name : {2}\n\ -Version : {1}\n\ -GraalVM : {3}\n\ -Stability: {6}\n\ -Origin : {4} -LIST_ComponentBasicInfo_Simple@={5};{0};{1};{2};{3};{4};{6};{7} -LIST_RequirementsHeader=Requirements -LIST_ErrorInComponentMetadata=There were errors reading component information: -LIST_ErrorInComponentMetadataItem= - {0} - -LIST_Help=\ - Usage:\n\ - gu list [-cJlv] [ [ ...]]\n\ -\n\ - The expression filters installed components. Can be a component ID,\ - or a regular expression, optionally enclosed in quotes or double quotes.\ - If no expression is given, all installed components are listed.\n\ -\n\ - Options:\n\ -\ -c, --catalog list components available in catalog. Same as "gu available" for compatibility.\n\ -\ -J, --json output in JSON format.\n\ -\ -l, --list-files list files. Only installed components.\n\ -\ -v, --verbose be verbose. Print more detailed information. - - -AVAILABLE_Help=\ - Usage:\n\ - gu available [-aCJlvV] [ [ ...]]\n\ -\n\ - The expression filters catalog components. Can be a component ID,\ - or a regular expression, optionally enclosed in quotes or double quotes.\ - If no expression is given, all installed components are listed.\n\ -\n\ - Options:\n\ -\ -a, --all-versions show all versions\n\ -\ -C, --custom-catalog use a specific catalog URL or local directory to locate components.\n\ -\ --edition show components from the specified edition\n\ -\ -J, --json output in JSON format.\n\ -\ -l, --list-files list files. Only installed components.\n\ -\ --show-core show core component\n\ -\ --show-updates show updated versions of components.\n\n\ -\ -v, --verbose be verbose. Print more detailed information.\n\ -\ -V, --use-version use specified version of components.\n\ -\n\ -Version can be specified as:\n\ -\ version - the specified version, and its newest patch\n\ -\ ~version - the specified version, and its newest patch (same as preceding form)\n\ -\ =version - precise version, including patch number\n\ -\ +version - the most recent version, newer or equal to the specified one\n\ -as part of "-V" switch. Can be also appended after component id, for example ruby=1.0 - -INFO_Help=\ - Usage:\n\ - gu info [-cCFJlLnprstuvV] [ ...]\n\ -\n\ - Print information about the component in the specified file or about a specific \ - component in the catalog.\n\ -\n\ - Options:\n\ -\ -c, --catalog treat parameters as component IDs from the catalog of GraalVM components. This is the default.\n\ -\ -C, --custom-catalog use a specific catalog URL or local directory to locate components.\n\ -\ --edition use catalogs from the specified edition\n\ -\ -J, --json output in JSON format.\n\ -\ -l, --list-files list files.\n\ -\ -L, --local-file treat parameters as local filenames of packaged components.\n\ -\ -n, --no-progress do not display download progress.\n\ -\ -p, --paths display full path in table listing.\n\ -\ -r, --ignore-open ignore errors when opening component archives. Continues with the next component.\n\ -\ -s, --no-verify-jars skip integrity verification of component archives\n\ -\ -t, --no-tables do NOT use table listings.\n\ -\ -u, --url interpret parameters as URLs of packaged components.\n\ -\ -v, --verbose be verbose. Print versions and dependency info.\n\ -\ -V, --use-version use specified version of components.\n\ -\n\ -Version can be specified as:\n\ -\ version - the specified version, and its newest patch\n\ -\ ~version - the specified version, and its newest patch (same as preceding form)\n\ -\ =version - precise version, including patch number\n\ -\ +version - the most recent version, newer or equal to the specified one\n\ -as part of "-V" switch. Can be also appended after component id, e.g. ruby=1.0 - -INFO_ClosingComponent=Error closing component bundle {0}: {1} -INFO_ErrorOpeningBundle=Invalid or corrupted component bundle {0}: {1} -INFO_ErrorReadingBundle=I/O error reading component bundle {0}: {1} -INFO_CorruptedBundleMetadata=Invalid or missing metadata {1} in bundle {0}: {2} -INFO_MissingFilename=Missing filename. - -INFO_ComponentShortListHeader=\ -File ComponentId Version Component name Stability\n\ --------------------------------------------------------------------------------------------------------- -# +20 +25 +11 +30 -# -# The following bundle is actually a String.format format pattern. -# The most important is the width and precision which should follow the header widths -INFO_ComponentShortList=%4$-20.20s%1$-25.25s%2$-11.11s%3$-30.30s%5$s - -INFO_ComponentLongListHeader=\ -Path\n\ - ComponentId Version Component name Stability\n\ -------------------------------------------------------------------------------------------------- -# +25 +20 +30 -# The following bundle is actually a String.format format pattern. -# The most important is the width and precision which should follow the header widths -INFO_ComponentLongList=%4$s\n %1$-21.21s%2$-20.20s%3$-30.30s%5$s - -INFO_ComponentNoFileHeader=\ -ComponentId Version Component name Stability\n\ --------------------------------------------------------------------------------------------------- -#+00 +25 +20 +30 -# -# The following bundle is actually a String.format format pattern. -# The most important is the width and precision which should follow the header widths -INFO_ComponentShortListNoFile=%1$-25.25s%2$-20.20s%3$-30.30s%5$s - -INFO_ComponentBasicInfo=\ -Filename : {3}\n\ -Name : {2}\n\ -ID : {0}\n\ -Version : {1}\n\ -GraalVM : {4}\n\ -Stability: {5} - -INFO_ComponentRequirementsHeader=Requirements: -INFO_ComponentRequirement=\t{0} = {1} - -INFO_ComponentBroken=Component bundle {0} is broken -INFO_ComponentErrorIndent=\t- {0} -INFO_ComponentWillNotInstall=Component bundle {0} cannot be installed -INFO_ComponentDependencyIndent=\t- {0} - -# Relative path from graalvm home to the rebuild-images tool -REBUILD_ToolRelativePath=lib/svm/bin/rebuild-images -REBUILD_ImageToolInterrupted=The image rebuild has been interrupted. -REBUILD_RewriteRebuildToolName=gu rebuild-images - - -INSTALL_LicenseAcceptedAt=The license {0} is already accepted on {1} for {2} ({3}). -INSTALL_AcceptLicense=The component(s) {0} requires you to accept the following license: {1} -INSTALL_AcceptSingleLicense=Enter "Y" to confirm and accept all the license(s). Enter "R" to the view the license text.\n\ - Any other input will cancel the installation: -INSTALL_LicensesToAccept=Component(s) selected for install require(s) you to accept license(s): -INSTALL_LicenseComponentStart={0} -INSTALL_LicenseComponentCont={0}, {1} -INSTALL_AcceptLicenseComponents=\t{2}: {0} - {1} -INSTALL_AcceptAllLicensesPrompt=Enter "Y" to confirm and accept all the license(s).\n\ - Enter a number to the see license text. Enter "c" to cancel the operation: -INSTALL_AcceptLicensePrompt=Do you accept this license (Y for "yes", any other input for "no") ? : -INSTALL_AcceptPromptResponseYes@=Yes|y -INSTALL_AcceptPromptResponseRead@=List|Lst|L|Read|R -INSTALL_AcceptPromptResponseAbort@=Cancel|c|exit|e -INSTALL_LicenseNumberInvalidEntry=The entry is not valid. Enter a number (1-{0}, "Y" or "c": -INSTALL_LicenseNumberOutOfRange=Invalid number, must be 1-{0}: -INSTALL_LicenseNotFound=License not found in archive at {0}. -INSTALL_ErrorHandlingLicenses=Error during processing of license(s): {0} -INSTALL_RequiredDependencies=Additional Components are required: -# {0} - component name -# {1} - component Id -# {2} - component version -# {3} - additional test 'required by' or empty -INSTALL_RequiredDependencyLine=\ {0} ({1}, version {2}){3} -# {0} - list of required component names/ids, see INSTALL_RequiredDependencyItem -INSTALL_RequiredDependencySuffix=, required by: {0} -INSTALL_RequiredDependencyItem={0} ({1}) -INSTALL_UnknownComponents=Missing required component(s): -# {0} - component Id -# {1} - additional test 'required by' or empty -INSTALL_UnknownComponentLine=\ {0}{1} -INSTALL_UnresolvedDependencies=There were unresolved dependencies, terminating installation. -INSTALL_UnknownComponentsNote1=Note: You can use "-c", e.g. \n\ - \tgu install -L -c {0}\n\ - to resolve dependencies using catalog(s) and download required additional components. -INSTALL_UnknownComponentsNote2=Note: You can use "-D", e.g. \n\ - \tgu install -L -D {0}\n\ - to search for dependencies in parent directories of the files provided on the command line. - -# {0} - native component ID, name of the package -# {1} - the component name. -UNINSTALL_NativeComponent={1} ({0}) is a native component, use system tools to remove it, e.g.\n\ -\ yum remove {0}\n -# {0} - native component ID, name of the package -# {1} - the component name. -UNINSTALL_BundledComponent={1} ({0}) is bundled in the base package, it cannot be removed. -# {0} - component ID -UNINSTALL_CoreComponent={0} is a core component and cannot be uninstalled. - -# {0} - the current version -UPGRADE_NoUpdateFound=No GraalVM upgrade is found for the version {0} -UPGRADE_NoUpdateLatestVersion=No upgrade of GraalVM core is necessary, {0} is the latest version. -# {0} - directory where a new installation should be created -UPGRADE_DirectoryNotWritable=New GraalVM installation cannot be created: directory {0} is not writable. -# {0} - directory where a new installation should be created -UPGRADE_TargetDirectoryExists=Cannot install GraalVM: file or directory {0} already exists. -UPGRADE_CantDeleteOldSymlink=Could not delete old symlink {0}: {1} -UPGRADE_CantCreateNewSymlink=Unable to create new symlink {0}: {1} -# {0} - version -# {2} - java prefix -UPGRADE_GraalVMDirName@=graalvm-java{2}-{0} -# {0} - version -# {1} - edition -# {2} - java prefix -UPGRADE_GraalVMDirNameEdition@=graalvm-{1}-java{2}-{0} -# {0} - required version -UPGRADE_NoVersionSatisfiesComponents=No GraalVM version satisfies all the requested components. At least {0} is required. -UPGRADE_ComponentsCannotMigrate=Some of the installed components cannot migrate to the new version. Please upgrade to a specific GraalVM version first. -UPGRADE_ComponentsMissingFromEdition=Some of the installed components may be missing from edition "{0}". Use --ignore-missing to install anyway. -UPGRADE_CannotMigrateLicense=Could not migrate license acceptance: component {0}, license ID {1}. -UPGRADE_MissingParameter=Missing required parameter. -UPGRADE_CannotDowngrade=Cannot downgrade to an old version {0}. Please install manually. -UPGRADE_PreparingInstall=\ -\n=========================================================================\n\ -\tPreparing to install GraalVM Core version {0}.\n\ -\tDestination directory: {1}\n\ -========================================================================= -UPGRADE_InstallingCore=Installing GraalVM Core version {0} to {1}... -UPGRADE_MigratingLicenses=Copying license info from {0} to {1}. -UPGRADE_WarningEditionDifferent=NOTE: Downloaded GraalVM Core {0} specifies different installation directory name: {1}. -UPGRADE_TargetExistsNotDirectory=New GraalVM Core is to be installed to {0}; the destination exists but is NOT a directory. -UPGRADE_TargetExistsNotEmpty=The destination directory {0} is not empty. -UPGRADE_TargetExistsContainsGraalVM=The destination directory {0} already contains a GraalVM version {1}. - -UPDATE_Help=\ - Usage:\n\ - gu update [-f] [param ...]\n\ -\n\ - Update some or all installed components to their latest patches in the current\n\ - installation. Will not install new GraalVM Core - use "gu install" to do so. - -UPGRADE_Help=\ - Usage:\n\ - gu upgrade [-cCdLnsSux] [version] [param ...]\n\ - gu update [-cCdLnsSux] [version] [param ...]\n\ -\n\ - Options:\n\ -\ -c, --catalog treat parameters as component IDs from a catalog of GraalVM components. This is the default.\n\ -\ -C, --custom-catalog use a specific catalog URL to locate components.\n\ -\ -d, --target-dir install into specified target dir, implies -S\n\ -\ --edition show components from the specified edition\n\ -\ -L, --local-file treat parameters as local filenames of packaged components.\n\ -\ -n, --no-progress do not display download progress.\n\ -\ -s, --no-verify-jars skip integrity verification of component archives\n\ -\ -S, --no-symlink do not create or update symlink\n\ -\ -u, --url interpret parameters as URLs of packaged components.\n\ -\ -x, --ignore-missing ignore missing components for the target version, install new core anyway\n\ -\n\ - If "version" is specified, the GraalVM will be updated to that version.\n\ -\n\ - The GraalVM core will be upgraded and existing components reinstalled in appropriate versions into the \n\ - new installation. Additional components to install may be specified as parameters. The install will fail if the\\n\ - updated GraalVM core does not support any of currently installed components. -x will force the installation and\n\ - will drop the unsupported component. -f will disable all version checks.\ -\n - -INFO_InvalidComponent=Invalid parameter: {0} -UPGRADE_NoSpecificVersion=GraalVM core is not available in version {0}. -UPGRADE_NoSpecificVersion2=GraalVM core is not available in version {0}. Pick e.g. {1}. - -# {0} - the native-image component ID. -REBUILD_RebuildImagesNotInstalled=Error: rebuild-images utility is not available. You may need to install "{0}" component. \n\ -Please refer to the documentation for details. - -INSTALL_WarnLocalDependencies=Warning: -D (use local files for dependencies) was specified without -L (use local files); there \ - are no locations to load local files from. -D will be ignored. - -INSTALL_CannotReplaceBundledComponent=The component {0} is bundled with the base GraalVM and cannot be replaced. -INSTALL_UsingNewerComponent=Using newer version of component {0} ({1}): {2} (the older version was: {3}) -INSTALL_CannotDigestLicense=Could not digest license text: {0} - -INSTALL_DownloadLicenseFile=License file -# {0} license name -INSTALL_DownloadLicenseName=Contents of "{0}" - -# [0} license Id -# {1} error message -WARN_LicenseNotRecorded=Warning: Acceptance of license {0} could not be recorded: {1} -UPGRADE_CannotMigrateGDS=Warning: Could not migrate GDS settings -# {0} symlink name -# {1} symlink target -UPGRADE_CreatingSymlink=Creating symlink to the new GraalVM Installation: {0} -> {1} -UPGRADE_UpdatingSymlink=Updating symlink to the new GraalVM Installation: {0} -> {1} - -# {0} - graalvm core name -# {1} - graalvm core version -# {2} - list of components -UPGRADE_MissingComponents=Components missing for {0} {1}: \n{2} -# {0} - component (short) ID -# {1} - component name -UPGRADE_MissingComponentItem=\t{0} ({1}) -# {0} - preceding list part, -# {1} - additional item. -UPGRADE_MissingComponentListPart={0},\n{1} -# {0} - list contents -UPGRADE_MissingComponentListFinish={0} - -@INSTALL_Error_ComponentDiffers_Report=\nBroken component and/or catalog: The remote component differs from the catalog information. \n\ - \ Catalog Component package\n\ - ---------------------------------------------------------------------------------\n\ - Id: %1$-35s %2$-35s\n\ - Version: %3$-35s %4$-35s\n\n -# The newline at start and the end of above message is deliberate - -INSTALL_Error_ComponentDiffers=Component info mismatch. diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/GraalVMInstaller.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/GraalVMInstaller.java deleted file mode 100644 index 4c4cec8f4f37..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/GraalVMInstaller.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ManagementStorage; - -/** - * - * @author sdedic - */ -public class GraalVMInstaller extends Installer { - private static final String SYMLINK_NAME = "active"; // NOI18N - - private Path currentInstallPath; - private boolean disableSymlinks; - private boolean createSymlink; - - public GraalVMInstaller(Feedback feedback, FileOperations fops, ComponentRegistry current, - ComponentInfo componentInfo, ComponentCollection collection, Archive a) { - super(feedback, fops, componentInfo, - new ComponentRegistry(feedback, - new TransientStorage( - componentInfo.getVersion(), - current.getGraalCapabilities(), componentInfo.getProvidedValues())), - collection, a); - } - - public Path getCurrentInstallPath() { - return currentInstallPath; - } - - public Path getInstalledPath() { - return getInstallPath().resolve(SystemUtils.getGraalVMJDKRoot(registry)); - } - - public void setCurrentInstallPath(Path currentInstallPath) { - this.currentInstallPath = currentInstallPath.normalize(); - } - - public boolean isDisableSymlinks() { - return disableSymlinks; - } - - public void setDisableSymlinks(boolean disableSymlinks) { - this.disableSymlinks = disableSymlinks; - } - - public boolean isCreateSymlink() { - return createSymlink; - } - - public void setCreateSymlink(boolean createSymlink) { - this.createSymlink = createSymlink; - } - - void createSymlink() throws IOException { - if (Files.getFileStore(getInstallPath()).supportsFileAttributeView("isSymbolicLink")) { - return; - } - createSymlink(findSymlink(getInstalledPath().getParent()).orElse(null)); - } - - Path createSymlink(Path linkFile) { - Path parent = linkFile == null ? getInstallPath().getParent() : linkFile.getParent(); - if (parent == null) { - return null; - } - Path linkTarget; - - try { - linkTarget = parent.relativize(getInstallPath()); - } catch (IllegalArgumentException ex) { - linkTarget = getInstallPath(); - } - if (!disableSymlinks) { - if (linkFile != null) { - boolean create = false; - try { - feedback.output("UPGRADE_UpdatingSymlink", linkFile, linkTarget); - Files.delete(linkFile); - create = true; - Files.createSymbolicLink(linkFile, linkTarget); - } catch (IOException ex) { - feedback.error( - create ? "UPGRADE_CantCreateNewSymlink" : "UPGRADE_CantDeleteOldSymlink", - ex, linkFile, ex.getLocalizedMessage()); - } - - } else if (createSymlink) { - Path linkSource = parent.resolve(SYMLINK_NAME); - try { - feedback.output("UPGRADE_CreatingSymlink", linkSource, linkTarget); - Files.createSymbolicLink(linkSource, linkTarget); - } catch (IOException ex) { - feedback.error( - "UPGRADE_CantCreateNewSymlink", - ex, linkFile, ex.getLocalizedMessage()); - } - } - } - return linkFile; - } - - Optional findSymlink(Path parentPath) throws IOException { - return Files.list(parentPath).filter((p) -> { - if (!Files.isSymbolicLink(p)) { - return false; - } - Path target; - try { - target = Files.readSymbolicLink(p); - return Files.isSameFile(p.resolveSibling(target), currentInstallPath); - } catch (IOException ex) { - // OK, symlink unreadable - return false; - } - }).findAny(); - } - - Path existingSymlink() throws IOException { - Path parentPath = getInstallPath().getParent(); - Optional existingLink = findSymlink(parentPath); - if (!existingLink.isPresent()) { - existingLink = findSymlink(getInstallPath().toRealPath().getParent()); - } - return existingLink.orElse(null); - } - - @Override - void installContent() throws IOException { - Path registryPath = getInstalledPath().resolve(SystemUtils.fromCommonRelative(CommonConstants.PATH_COMPONENT_STORAGE)); - Files.createDirectories(registryPath); - super.installContent(); - } - - /** - * Does not write to the new installation, and extracts version info from the GraalVM core - * component. - */ - static class TransientStorage implements ManagementStorage { - private final Map graalCaps = new HashMap<>(); - - TransientStorage(Version newGraalVersion, Map graalCaps, Map newCaps) { - this.graalCaps.putAll(graalCaps); - graalCaps.put(BundleConstants.GRAAL_VERSION, newGraalVersion.toString()); - for (String s : newCaps.keySet()) { - graalCaps.put(s, newCaps.get(s).toString()); - } - } - - @Override - public void deleteComponent(String id) throws IOException { - } - - @Override - public Set listComponentIDs() throws IOException { - return Collections.emptySet(); - } - - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - return ci; - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - // no component is present - return null; - } - - @Override - public Map loadGraalVersionInfo() { - return Collections.unmodifiableMap(graalCaps); - } - - @Override - public Map> readReplacedFiles() throws IOException { - return Collections.emptyMap(); - } - - @Override - public void saveComponent(ComponentInfo info) throws IOException { - } - - @Override - public void updateReplacedFiles(Map> replacedFiles) throws IOException { - } - - @Override - public Date licenseAccepted(ComponentInfo info, String licenseID) { - return null; - } - - @Override - public void recordLicenseAccepted(ComponentInfo info, String licenseID, String licenseText, Date d) throws IOException { - } - - @Override - public Map> findAcceptedLicenses() { - return Collections.emptyMap(); - } - - @Override - public String licenseText(String licID) { - return ""; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InfoCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InfoCommand.java deleted file mode 100644 index 40b16d7f2f7d..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InfoCommand.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.zip.ZipException; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_ERRORS; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_FILENAME; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_REQUIRES; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_PROBLEMS; -import org.graalvm.component.installer.ComponentInstaller; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.Verifier; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONObject; - -/** - * Command to query component bundles. - */ -public class InfoCommand extends QueryCommandBase { - private static final Map OPTIONS = new HashMap<>(); - - static { - OPTIONS.putAll(BASE_OPTIONS); - OPTIONS.putAll(ComponentInstaller.componentOptions); - - OPTIONS.put(Commands.OPTION_NO_VERIFY_JARS, ""); - OPTIONS.put(Commands.OPTION_FULL_PATHS, ""); - OPTIONS.put(Commands.OPTION_IGNORE_OPEN_ERRORS, ""); - OPTIONS.put(Commands.OPTION_SUPPRESS_TABLE, ""); - OPTIONS.put(Commands.OPTION_NO_DOWNLOAD_PROGRESS, ""); - - OPTIONS.put(Commands.LONG_OPTION_NO_VERIFY_JARS, Commands.OPTION_NO_VERIFY_JARS); - OPTIONS.put(Commands.LONG_OPTION_FULL_PATHS, Commands.OPTION_FULL_PATHS); - OPTIONS.put(Commands.LONG_OPTION_IGNORE_OPEN_ERRORS, Commands.OPTION_IGNORE_OPEN_ERRORS); - OPTIONS.put(Commands.LONG_OPTION_SUPPRESS_TABLE, Commands.OPTION_SUPPRESS_TABLE); - OPTIONS.put(Commands.LONG_OPTION_NO_DOWNLOAD_PROGRESS, Commands.OPTION_NO_DOWNLOAD_PROGRESS); - - OPTIONS.put(Commands.OPTION_VERSION, "s"); - OPTIONS.put(Commands.LONG_OPTION_VERSION, Commands.OPTION_VERSION); - - OPTIONS.put(Commands.OPTION_USE_EDITION, "s"); - OPTIONS.put(Commands.LONG_OPTION_USE_EDITION, Commands.OPTION_USE_EDITION); - } - - private boolean ignoreOpenErrors; - private boolean verifyJar; - private boolean fullPath; - private boolean suppressTable; - private Version.Match versionFilter; - private boolean noComponentPath; - - private final List components = new ArrayList<>(); - private final Map map = new HashMap<>(); - private final Map files = new HashMap<>(); - - @Override - public Map supportedOptions() { - return OPTIONS; - } - - public boolean isSuppressTable() { - return suppressTable; - } - - public void setSuppressTable(boolean suppressTable) { - this.suppressTable = suppressTable; - } - - public boolean isIgnoreOpenErrors() { - return ignoreOpenErrors; - } - - public void setIgnoreOpenErrors(boolean ignoreOpenErrors) { - this.ignoreOpenErrors = ignoreOpenErrors; - } - - public boolean isVerifyJar() { - return verifyJar; - } - - public void setVerifyJar(boolean verifyJar) { - this.verifyJar = verifyJar; - } - - public boolean isFullPath() { - return fullPath; - } - - public void setFullPath(boolean fullPath) { - this.fullPath = fullPath; - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - super.init(commandInput, feedBack); - ignoreOpenErrors = input.optValue(Commands.OPTION_IGNORE_OPEN_ERRORS) != null; - verifyJar = input.optValue(Commands.OPTION_NO_VERIFY_JARS) == null; - suppressTable = input.optValue(Commands.OPTION_SUPPRESS_TABLE) != null; - fullPath = input.optValue(Commands.OPTION_FULL_PATHS) != null; - - String vf = input.optValue(Commands.OPTION_VERSION); - if (vf != null) { - versionFilter = Version.versionFilter(vf); - } - - noComponentPath = !(input.hasOption(Commands.OPTION_FILES) || input.hasOption(Commands.OPTION_URLS)); - } - - void collectComponents() throws IOException { - for (Iterator it = input.existingFiles().matchVersion(versionFilter).allowIncompatible().iterator(); it.hasNext();) { - ComponentParam cp; - try { - cp = it.next(); - } catch (FailedOperationException ex) { - feedback.error("INFO_InvalidComponent", ex, ex.getLocalizedMessage()); - continue; - } - try { - // verifyjar set to false, as Verifier is not supported in SVM - // components.add(ldr = new ComponentPackageLoader(new JarFile(f, false), - // feedback)); - processComponentParam(cp); - } catch (ZipException ex) { - if (ignoreOpenErrors) { - feedback.error("INFO_ErrorOpeningBundle", ex, - cp.getDisplayName(), - ex.getLocalizedMessage()); - } else { - throw ex; - } - } catch (MetadataException ex) { - if (ignoreOpenErrors) { - feedback.error("INFO_CorruptedBundleMetadata", ex, - cp.getDisplayName(), - ex.getOffendingHeader(), - ex.getLocalizedMessage()); - } else { - throw ex; - } - } catch (IOException ex) { - if (ignoreOpenErrors) { - feedback.error("INFO_ErrorReadingBundle", ex, - cp.getDisplayName(), - ex.getLocalizedMessage()); - } else { - throw ex; - } - } - } - } - - @Override - public int execute() throws IOException { - if (input.optValue(Commands.OPTION_HELP) != null) { - feedback.output("INFO_Help"); - return 0; - } - if (!input.hasParameter()) { - feedback.error("INFO_MissingFilename", null); - return 1; - } - try { - collectComponents(); - printTable = getComponents().size() > 1 && !isVerbose() && !suppressTable; - super.printComponents(); - } finally { - for (ComponentParam c : components) { - try { - c.close(); - } catch (IOException ex) { - ComponentInfo ci = c.createMetaLoader().getComponentInfo(); - feedback.error("INFO_ClosingComponent", ex, - ci == null ? c.getSpecification() : shortenComponentId(ci), - ex.getLocalizedMessage()); - } - } - } - return 0; - } - - void processComponentParam(ComponentParam cp) throws IOException { - MetadataLoader ldr = cp.createMetaLoader(); - - components.add(cp); - loadComponentDetails(cp, ldr); - // registerFile(f, ldr.getComponentInfo(), ldr); - addComponent(cp, ldr.getComponentInfo()); - - } - - void registerFile(ComponentParam param, ComponentInfo info, MetadataLoader ldr) { - files.put(info, param); - map.put(info, ldr); - } - - void loadComponentDetails(ComponentParam param, MetadataLoader ldr) throws IOException { - ldr.infoOnly(true); - ComponentInfo info = ldr.getComponentInfo(); - registerFile(param, info, ldr); - if (isListFiles()) { - ldr.loadPaths(); - } - } - - @Override - void printHeader() { - if (printTable) { - if (fullPath) { - feedback.output("INFO_ComponentLongListHeader"); - } else if (noComponentPath) { - feedback.output("INFO_ComponentNoFileHeader"); - } else { - feedback.output("INFO_ComponentShortListHeader"); - } - } - } - - protected String filePath(ComponentInfo info) { - ComponentParam p = files.get(info); - if (fullPath) { - return p.getFullPath(); - } else { - String s = p.getShortName(); - int idx = s.lastIndexOf('.'); - return idx == -1 ? s : s.substring(0, idx); - } - } - - @Override - void printDetails(ComponentParam param, ComponentInfo info) { - if (isJson()) { - super.printDetails(param, info); - JSONObject jsonComponent = getJSONComponent(); - jsonComponent.put(JSON_KEY_COMPONENT_FILENAME, param.getFullPath()); - List keys = new ArrayList<>(info.getRequiredGraalValues().keySet()); - keys.remove(CommonConstants.CAP_GRAALVM_VERSION); - if (!keys.isEmpty()) { - JSONObject requires = new JSONObject(); - jsonComponent.put(JSON_KEY_COMPONENT_REQUIRES, requires); - Collections.sort(keys); - for (String cap : keys) { - requires.put(cap, info.getRequiredGraalValues().get(cap)); - } - } - MetadataLoader ldr = map.get(info); - List errs = ldr.getErrors(); - if (!errs.isEmpty()) { - JSONArray errors = new JSONArray(); - jsonComponent.put(JSON_KEY_COMPONENT_ERRORS, errors); - for (InstallerStopException ex : errs) { - errors.put(ex.getLocalizedMessage()); - } - } - Verifier vfy = new Verifier(feedback, input.getLocalRegistry(), catalog).collect(true).validateRequirements(info); - if (vfy.hasErrors()) { - JSONArray problems = new JSONArray(); - jsonComponent.put(JSON_KEY_COMPONENT_PROBLEMS, problems); - for (DependencyException ex : vfy.getErrors()) { - problems.put(ex.getLocalizedMessage()); - } - } - } else if (printTable) { - String line = String.format(feedback.l10n(fullPath ? "INFO_ComponentLongList" : (noComponentPath ? "INFO_ComponentShortListNoFile" : "INFO_ComponentShortList")), - shortenComponentId(info), val(info.getVersion().displayString()), val(info.getName()), - filePath(info), info.getStability().displayName(feedback)); - feedback.verbatimOut(line, false); - } else { - feedback.output("INFO_ComponentBasicInfo", - shortenComponentId(info), val(info.getVersion().displayString()), val(info.getName()), - param.getFullPath(), findRequiredGraalVMVersion(info), info.getStability().displayName(feedback)); - List keys = new ArrayList<>(info.getRequiredGraalValues().keySet()); - keys.remove(CommonConstants.CAP_GRAALVM_VERSION); - if (!keys.isEmpty() && feedback.verboseOutput("INFO_ComponentRequirementsHeader")) { - Collections.sort(keys); - for (String cap : keys) { - feedback.verboseOutput("INFO_ComponentRequirement", - getRegistry().localizeCapabilityName(cap), - info.getRequiredGraalValues().get(cap)); - } - } - MetadataLoader ldr = map.get(info); - List errs = ldr.getErrors(); - if (!errs.isEmpty()) { - feedback.message("INFO_ComponentBroken", files.get(info)); - for (InstallerStopException ex : errs) { - feedback.message("INFO_ComponentErrorIndent", ex.getLocalizedMessage()); - } - } - - Verifier vfy = new Verifier(feedback, input.getLocalRegistry(), catalog).collect(true).validateRequirements(info); - if (vfy.hasErrors()) { - feedback.message("INFO_ComponentWillNotInstall", shortenComponentId(info)); - for (DependencyException ex : vfy.getErrors()) { - feedback.message("INFO_ComponentDependencyIndent", ex.getLocalizedMessage()); - } - } - - } - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InstallCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InstallCommand.java deleted file mode 100644 index df612be2e3ed..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/InstallCommand.java +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; -import java.util.zip.ZipException; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.ComponentInstaller; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.UserAbortException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.model.Verifier; -import org.graalvm.component.installer.persist.MetadataLoader; - -/** - * Implementation of 'add' command. - */ -public class InstallCommand implements InstallerCommand { - private static final Logger LOG = Logger.getLogger(InstallCommand.class.getName()); - - private static final Map OPTIONS = new HashMap<>(); - - private CommandInput input; - private Feedback feedback; - private boolean ignoreFailures; - private boolean force; - private boolean validateBeforeInstall; - private boolean validateDownload; - private boolean allowUpgrades; - // verify archives by default - private boolean verifyJar = true; - /** - * Was a file:// component location encountered ? - */ - private boolean wasFile; - - private PostInstProcess postinstHelper; - - static { - OPTIONS.put(Commands.OPTION_DRY_RUN, ""); - OPTIONS.put(Commands.OPTION_FORCE, ""); - OPTIONS.put(Commands.OPTION_REPLACE_COMPONENTS, ""); - OPTIONS.put(Commands.OPTION_REPLACE_DIFFERENT_FILES, ""); - OPTIONS.put(Commands.OPTION_VALIDATE, ""); - OPTIONS.put(Commands.OPTION_VALIDATE_DOWNLOAD, ""); - OPTIONS.put(Commands.OPTION_IGNORE_FAILURES, ""); - OPTIONS.put(Commands.OPTION_FAIL_EXISTING, ""); - OPTIONS.put(Commands.OPTION_NO_DOWNLOAD_PROGRESS, ""); - OPTIONS.put(Commands.OPTION_NO_VERIFY_JARS, ""); - OPTIONS.put(Commands.OPTION_LOCAL_DEPENDENCIES, ""); - OPTIONS.put(Commands.OPTION_NO_DEPENDENCIES, ""); - - OPTIONS.put(Commands.LONG_OPTION_DRY_RUN, Commands.OPTION_DRY_RUN); - OPTIONS.put(Commands.LONG_OPTION_FORCE, Commands.OPTION_FORCE); - OPTIONS.put(Commands.LONG_OPTION_REPLACE_COMPONENTS, Commands.OPTION_REPLACE_COMPONENTS); - OPTIONS.put(Commands.LONG_OPTION_REPLACE_DIFFERENT_FILES, Commands.OPTION_REPLACE_DIFFERENT_FILES); - OPTIONS.put(Commands.LONG_OPTION_VALIDATE, Commands.OPTION_VALIDATE); - OPTIONS.put(Commands.LONG_OPTION_VALIDATE_DOWNLOAD, Commands.OPTION_VALIDATE_DOWNLOAD); - OPTIONS.put(Commands.LONG_OPTION_IGNORE_FAILURES, Commands.OPTION_IGNORE_FAILURES); - OPTIONS.put(Commands.LONG_OPTION_FAIL_EXISTING, Commands.OPTION_FAIL_EXISTING); - OPTIONS.put(Commands.LONG_OPTION_NO_DOWNLOAD_PROGRESS, Commands.OPTION_NO_DOWNLOAD_PROGRESS); - OPTIONS.put(Commands.LONG_OPTION_NO_VERIFY_JARS, Commands.OPTION_NO_VERIFY_JARS); - OPTIONS.put(Commands.LONG_OPTION_LOCAL_DEPENDENCIES, Commands.OPTION_LOCAL_DEPENDENCIES); - OPTIONS.put(Commands.LONG_OPTION_NO_DEPENDENCIES, Commands.OPTION_NO_DEPENDENCIES); - - OPTIONS.put(Commands.OPTION_USE_EDITION, "s"); - OPTIONS.put(Commands.LONG_OPTION_USE_EDITION, Commands.OPTION_USE_EDITION); - - OPTIONS.putAll(ComponentInstaller.componentOptions); - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.input = commandInput; - this.feedback = feedBack; - - ignoreFailures = this.input.optValue(Commands.OPTION_IGNORE_FAILURES) != null; - validateBeforeInstall = this.input.optValue(Commands.OPTION_VALIDATE) != null; - validateDownload = this.input.optValue(Commands.OPTION_VALIDATE_DOWNLOAD) != null; - verifyJar = input.optValue(Commands.OPTION_NO_VERIFY_JARS) == null; - postinstHelper = new PostInstProcess(input, feedBack); - } - - public boolean isVerifyJar() { - return verifyJar; - } - - public void setVerifyJar(boolean verifyJar) { - this.verifyJar = verifyJar; - } - - public boolean isAllowUpgrades() { - return allowUpgrades; - } - - public void setAllowUpgrades(boolean allowUpgrades) { - this.allowUpgrades = allowUpgrades; - } - - @Override - public Map supportedOptions() { - return OPTIONS; - } - - public InstallCommand() { - } - - /** - * Installers attached to individual parameters. - */ - Map realInstallers = new LinkedHashMap<>(); - - /** - * Original (possibly catalog) ComponentInfos. - */ - Map parameterInfos = new LinkedHashMap<>(); - - private String current; - - private StringBuilder parameterList = new StringBuilder(); - - /** - * Minimum required GraalVM version for the to-be-installed content. - */ - private Version minRequiredGraalVersion; - - protected void executionInit() throws IOException { - input.getLocalRegistry().verifyAdministratorAccess(); - input.existingFiles().setVerifyJars(verifyJar); - - minRequiredGraalVersion = input.getLocalRegistry().getGraalVersion(); - } - - @Override - public int execute() throws IOException { - executionInit(); - if (input.optValue(Commands.OPTION_HELP) != null) { - feedback.output("INSTALL_Help"); - return 0; - } - if (!input.hasParameter()) { - feedback.output("INSTALL_ParametersMissing"); - return 1; - } - if (input.optValue(Commands.OPTION_LOCAL_DEPENDENCIES) != null && - input.optValue(Commands.OPTION_FILES) == null) { - feedback.error("INSTALL_WarnLocalDependencies", null); - } - try { - executeStep(this::prepareInstallation, false); - if (validateBeforeInstall) { - return 0; - } - executeStep(this::acceptLicenses, false); - executeStep(this::completeInstallers, false); - executeStep(this::acceptLicenses, false); - executeStep(this::doInstallation, false); - // execute the post-install steps for all processed installers - executeStep(this::printMessages, true); - } finally { - for (Map.Entry e : realInstallers.entrySet()) { - ComponentParam p = e.getKey(); - Installer i = e.getValue(); - p.close(); - if (i != null) { - i.close(); - } - } - } - return 0; - } - - /** - * License IDs processed by the user. - */ - private Set processedLicenses = new HashSet<>(); - - /** - * Licenses, which must be accepted at most before the installation. - */ - private Map> licensesToAccept = new LinkedHashMap<>(); - - /** - * Adds a license to be accepted. Does not add a license ID that has been already processed in - * previous round(s). - * - * @param id license ID - * @param ldr loader that can deliver the license details. - */ - void addLicenseToAccept(String id, MetadataLoader ldr) { - if (processedLicenses.contains(id)) { - return; - } - licensesToAccept.computeIfAbsent(id, (x) -> new ArrayList<>()).add(ldr); - } - - protected Version.Match matchInstallVesion() { - return input.getLocalRegistry().getGraalVersion().match( - allowUpgrades ? Version.Match.Type.INSTALLABLE : Version.Match.Type.COMPATIBLE); - } - - public void addLicenseToAccept(Installer inst, MetadataLoader ldr) { - if (ldr.getLicenseType() != null) { - String path = ldr.getLicensePath(); - if (inst != null && path != null) { - if (!SystemUtils.isRemotePath(path)) { - inst.setLicenseRelativePath(SystemUtils.fromCommonRelative(ldr.getLicensePath())); - } - } - addLicenseToAccept(ldr); - } - } - - public void addLicenseToAccept(MetadataLoader ldr) { - String licId = ldr.getLicenseID(); - if (licId == null) { - String tp = ldr.getLicenseType(); - if (tp == null) { - return; - } - if (Pattern.matches("[-_., 0-9A-Za-z]+", tp)) { // NOI18N - licId = tp; - } else { - // better make a digest - try { - MessageDigest dg = MessageDigest.getInstance("SHA-256"); // NOI18N - byte[] result = dg.digest(tp.getBytes("UTF-8")); - licId = SystemUtils.fingerPrint(result, false); - } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { - feedback.error("INSTALL_CannotDigestLicense", ex, ex.getLocalizedMessage()); - licId = Integer.toHexString(tp.hashCode()); - } - } - } - addLicenseToAccept(licId, ldr); - } - - /** - * Implied dependencies discovered during preparation. - */ - private List dependencies = new ArrayList<>(); - private Map> dependencyMap = new HashMap<>(); - - /** - * Unresolved dependencies, which will be reported all at once. - */ - private Set unresolvedDependencies = new HashSet<>(); - private Set knownDeps = new HashSet<>(); - - void cleanDependencies() { - dependencies = new ArrayList<>(); - // do not clean knownDeps, prevents duplicates. - } - - public List getDependencies() { - return Collections.unmodifiableList(dependencies); - } - - void addDependencies(ComponentInfo ci) { - if (input.hasOption(Commands.OPTION_NO_DEPENDENCIES)) { - return; - } - - // dependencies are scanned breadth-first; so the deeper dependencies are - // later in the iterator order. Installers from dependencies will be reversed - // in registerComponent - Set deps = new LinkedHashSet<>(); - - LOG.log(Level.FINE, "Inspecting dependencies of {0}", ci); - Set errors = input.getRegistry().findDependencies(ci, true, Boolean.FALSE, deps); - LOG.log(Level.FINE, "Direct dependencies: {0}, errors: {1}", new Object[]{deps, errors}); - if (errors != null) { - unresolvedDependencies.addAll(errors); - for (String s : errors) { - dependencyMap.computeIfAbsent(s, (id) -> new HashSet<>()).add(ci); - } - } - - for (ComponentInfo i : deps) { - // knownDeps may contain multiple component versions, this - // will be sorted later, when converting to Installers. - if (!knownDeps.add(i)) { - continue; - } - ComponentParam p = input.existingFiles().createParam(i.getId(), i); - dependencies.add(p); - dependencyMap.computeIfAbsent(i.getId(), (id) -> new HashSet<>()).add(ci); - } - } - - void printRequiredComponents() throws IOException { - if (dependencies.isEmpty()) { - return; - } - feedback.output("INSTALL_RequiredDependencies"); - for (ComponentParam p : dependencies) { - ComponentInfo ci = p.createMetaLoader().getComponentInfo(); - feedback.output("INSTALL_RequiredDependencyLine", p.getDisplayName(), ci.getId(), ci.getVersion().displayString(), - printComponentList(dependencyMap.get(ci.getId()))); - } - } - - boolean verifyInstaller(Installer inst) { - ComponentInfo info = inst.getComponentInfo(); - Verifier vrf = inst.createVerifier(); - vrf.setVersionMatch(matchInstallVesion()); - vrf.validateRequirements(info); - boolean keep = force || vrf.shouldInstall(info); - if (!keep) { - // component will be skipped, do not bother with validation - feedback.output("INSTALL_ComponentAlreadyInstalled", inst.getComponentInfo().getName(), inst.getComponentInfo().getId()); - return false; - } - ComponentInfo existing = input.getLocalRegistry().findComponent(info.getId()); - if (existing != null) { - // will refuse to install existing bundled components: - if (existing.getDistributionType() != DistributionType.OPTIONAL) { - throw new DependencyException.Conflict( - existing.getId(), info.getVersionString(), existing.getVersionString(), - feedback.l10n("INSTALL_CannotReplaceBundledComponent", - existing.getName(), existing, existing.getVersionString())); - } - } - Version minV = vrf.getMinVersion(); - if (minV != null && minV.compareTo(this.minRequiredGraalVersion) > 0) { - minRequiredGraalVersion = minV; - } - addDependencies(info); - return true; - } - - String printComponentList(Collection requestors) { - if (requestors == null || requestors.isEmpty()) { - return ""; // NOI18N - } - StringBuilder sb = new StringBuilder(); - List infos = new ArrayList<>(requestors); - Collections.sort(infos, (c1, c2) -> c1.getId().compareTo(c2.getId())); - for (ComponentInfo i : infos) { - if (sb.length() > 0) { - sb.append(", "); - } - sb.append(feedback.l10n("INSTALL_RequiredDependencyItem", i.getName(), i.getId())); - } - return feedback.l10n("INSTALL_RequiredDependencySuffix", sb.toString()); - } - - void checkDependencyErrors() { - if (unresolvedDependencies.isEmpty()) { - return; - } - feedback.error("INSTALL_UnknownComponents", null); - List ordered = new ArrayList<>(unresolvedDependencies); - Collections.sort(ordered); - for (String s : ordered) { - feedback.error("INSTALL_UnknownComponentLine", null, s, - printComponentList(dependencyMap.get(s))); - } - if (!input.getRegistry().isRemoteEnabled()) { - feedback.error("INSTALL_UnknownComponentsNote1", null, parameterList.toString()); - } - if (wasFile && !input.hasOption(Commands.OPTION_LOCAL_DEPENDENCIES)) { - feedback.error("INSTALL_UnknownComponentsNote2", null, parameterList.toString()); - } - throw feedback.failure("INSTALL_UnresolvedDependencies", null); - } - - private void appendParameterText() { - String s = input.peekParameter(); - if (parameterList.length() > 0) { - parameterList.append(" "); // NOI18N - } - parameterList.append(s); - } - - /** - * True during dependency processing. Dependencies should be inserted at the start, so their - * order is reversed (most deepest dependencies first). That means that if a component already - * exists, it must be reinserted at the start. - */ - private boolean installDependencies; - - protected boolean registerComponent(Installer inst, ComponentParam p) throws IOException { - ComponentInfo info = inst.getComponentInfo(); - Installer existing = installerMap.get(info.getId()); - - Installer removedInstaller = null; - - if (existing == null) { - installerMap.put(info.getId(), inst); - if (installDependencies) { - installers.add(0, inst); - } else { - installers.add(inst); - } - return true; - } else { - int i = installers.indexOf(existing); - ComponentInfo exInfo = existing.getComponentInfo(); - int newer = exInfo.getVersion().compareTo(info.getVersion()); - if (newer < 0) { - feedback.verboseOutput("INSTALL_UsingNewerComponent", info.getId(), info.getName(), - info.getVersion().displayString(), exInfo.getVersion().displayString()); - - removedInstaller = installerMap.put(info.getId(), inst); - if (installDependencies) { - // must reinsert at the start: later items may depend on this one - installers.remove(i); - installers.add(0, inst); - } else { - // replace at the same position, to mainain commandline order - installers.set(i, inst); - } - existing.close(); - if (removedInstaller != null) { - realInstallers.remove(p); - } - return true; - } else { - Installer toReplace = inst.isComplete() ? inst : existing; - // if dependencies are processed, move the installer to the front - // of the work queue, to maintain the depenency-first order. - if (installDependencies) { - installers.remove(existing); - installers.add(0, toReplace); - installerMap.put(info.getId(), toReplace); - } else if (!existing.isComplete() && inst.isComplete()) { - // replace proxy for real installer: - installers.set(i, toReplace); - installerMap.put(info.getId(), toReplace); - } - - return false; - } - } - } - - protected void processComponents(Iterable toProcess) throws IOException { - for (Iterator it = toProcess.iterator(); it.hasNext();) { - appendParameterText(); - ComponentParam p = it.next(); - feedback.output(p.isComplete() ? "INSTALL_VerboseProcessingArchive" : "INSTALL_VerboseProcessingComponent", p.getDisplayName()); - current = p.getSpecification(); - MetadataLoader ldr = validateDownload ? p.createFileLoader() : p.createMetaLoader(); - Installer inst = createInstaller(p, ldr); - if (!verifyInstaller(inst)) { - continue; - } - if (registerComponent(inst, p)) { - addLicenseToAccept(inst, ldr); - if (p.isComplete()) { - // null realInstaller will be handled in completeInstallers() later. - realInstallers.put(p, inst); - } else { - realInstallers.put(p, null); - } - } - current = null; - - URL remote = ldr.getComponentInfo().getRemoteURL(); - if (remote == null || remote.getProtocol().equalsIgnoreCase("file")) { - wasFile = true; - } - } - - } - - protected void prevalidateInstallers() throws IOException { - for (Installer i : new ArrayList<>(installers)) { - if (validateBeforeInstall) { - current = i.getComponentInfo().getName(); - i.validateAll(); - } - } - } - - protected void prepareInstallation() throws IOException { - processComponents(input.existingFiles()); - // first check after explicit components have been processed. - checkDependencyErrors(); - if (dependencies.isEmpty()) { - return; - } - // dependencies were scanned recursively; so just one additional pass should - // be sufficient - try { - installDependencies = true; - processComponents(new ArrayList<>(dependencies)); - } finally { - installDependencies = false; - } - printRequiredComponents(); - checkDependencyErrors(); - prevalidateInstallers(); - } - - public void setIgnoreFailures(boolean ignoreFailures) { - this.ignoreFailures = ignoreFailures; - } - - public void setForce(boolean force) { - this.force = force; - } - - public void setValidateBeforeInstall(boolean validateBeforeInstall) { - this.validateBeforeInstall = validateBeforeInstall; - } - - public void setValidateDownload(boolean validateDownload) { - this.validateDownload = validateDownload; - } - - void executeStep(Step s, boolean close) throws IOException { - boolean ok = false; - try { - s.execute(); - ok = true; - } catch (ZipException ex) { - feedback.error("INSTALL_InvalidComponentArchive", ex, current); - throw ex; - } catch (UserAbortException ex) { - throw ex; - } catch (InstallerStopException | IOException ex) { - if (ignoreFailures) { - if (current == null) { - feedback.error("INSTALL_IgnoreFailedInstallation", ex, - ex.getLocalizedMessage()); - } else { - feedback.error("INSTALL_IgnoreFailedInstallation2", ex, - current, ex.getLocalizedMessage()); - } - } else { - if (current != null) { - feedback.error("INSTALL_ErrorDuringProcessing", ex, current, ex.getLocalizedMessage()); - } - throw ex; - } - } finally { - if (!ok) { - for (Installer inst : executedInstallers) { - inst.revertInstall(); - } - } - if (close || !ok) { - for (Installer inst : installers) { - try { - inst.close(); - } catch (IOException ex) { - // expected - } - } - } - } - } - - interface Step { - void execute() throws IOException; - } - - void printMessages() { - postinstHelper.run(); - } - - /** - * Creates installers with complete info. Revalidates the installers as they are now complete. - */ - void completeInstallers() throws IOException { - List allDependencies = new ArrayList<>(); - List in = new ArrayList<>(realInstallers.keySet()); - do { - cleanDependencies(); - completeInstallers0(in); - allDependencies.addAll(dependencies); - in = dependencies; - // print required components prior to download - printRequiredComponents(); - installDependencies = true; - } while (!in.isEmpty()); - dependencies = allDependencies; - checkDependencyErrors(); - } - - void completeInstallers0(List in) throws IOException { - // now fileName real installers for parameters which were omitted - for (ComponentParam p : in) { - Installer i = realInstallers.get(p); - if (i == null) { - MetadataLoader floader = p.createFileLoader(); - ComponentInfo initialInfo = parameterInfos.get(p); - ComponentInfo finfo = floader.getComponentInfo(); - if (initialInfo != null && (!initialInfo.getId().equals(finfo.getId()) || - !initialInfo.getVersion().equals(finfo.getVersion()))) { - String msg = String.format( - feedback.l10n("@INSTALL_Error_ComponentDiffers_Report"), - initialInfo.getId(), finfo.getId(), - initialInfo.getVersionString(), finfo.getVersionString()); - feedback.verbatimPart(msg, true, false); - throw feedback.failure("INSTALL_Error_ComponentDiffers", null); - } - i = createInstaller(p, floader); - if (!verifyInstaller(i)) { - continue; - } - addLicenseToAccept(i, floader); - registerComponent(i, p); - - if (validateBeforeInstall) { - current = i.getComponentInfo().getName(); - i.validateAll(); - } else { - if (!force) { - i.validateRequirements(); - } - } - realInstallers.put(p, i); - } - } - } - - void doInstallation() throws IOException { - for (Installer i : installers) { - current = i.getComponentInfo().getName(); - ensureExistingComponentRemoved(i.getComponentInfo()); - executedInstallers.add(i); - - i.setComponentDirectories(input.getLocalRegistry().getComponentDirectories()); - i.install(); - postinstHelper.addComponentInfo(i.getComponentInfo()); - } - } - - void ensureExistingComponentRemoved(ComponentInfo info) throws IOException { - String componentId = info.getId(); - ComponentInfo oldInfo = input.getLocalRegistry().loadSingleComponent(componentId, true); - if (oldInfo == null) { - feedback.output("INSTALL_InstallNewComponent", - info.getId(), info.getName(), info.getVersionString()); - } else { - Uninstaller uninstaller = new Uninstaller(feedback, - input.getFileOperations(), oldInfo, input.getLocalRegistry()); - uninstaller.setInstallPath(input.getGraalHomePath()); - uninstaller.setDryRun(input.optValue(Commands.OPTION_DRY_RUN) != null); - uninstaller.setPreservePaths( - new HashSet<>(input.getLocalRegistry().getPreservedFiles(oldInfo))); - - feedback.output("INSTALL_RemoveExistingComponent", - oldInfo.getId(), oldInfo.getName(), oldInfo.getVersionString(), - info.getId(), info.getName(), info.getVersionString()); - uninstaller.uninstall(); - } - } - - /** - * Installers for individual component IDs. - */ - private final Map installerMap = new HashMap<>(); - - /** - * The installation sequence; dependencies first. - */ - private final List installers = new ArrayList<>(); - private final List executedInstallers = new ArrayList<>(); - - List getInstallers() { - return installers; - } - - protected void configureInstaller(Installer inst) { - inst.setInstallPath(input.getGraalHomePath()); - inst.setDryRun(input.optValue(Commands.OPTION_DRY_RUN) != null); - force = input.optValue(Commands.OPTION_FORCE) != null; - - inst.setFailOnExisting(input.optValue(Commands.OPTION_FAIL_EXISTING) != null); - inst.setReplaceComponents(force || input.optValue(Commands.OPTION_REPLACE_COMPONENTS) != null); - inst.setIgnoreRequirements(force); - inst.setReplaceDiferentFiles(force || input.optValue(Commands.OPTION_REPLACE_DIFFERENT_FILES) != null); - if (validateBeforeInstall) { - inst.setDryRun(true); - } - } - - Map permissions; - Map symlinks; - ComponentInfo fullInfo; - - Installer createInstaller(ComponentParam p, MetadataLoader ldr) throws IOException { - ComponentInfo partialInfo; - partialInfo = ldr.getComponentInfo(); - parameterInfos.putIfAbsent(p, partialInfo); - feedback.verboseOutput("INSTALL_PrepareToInstall", - p.getDisplayName(), - partialInfo.getId(), - partialInfo.getVersionString(), - partialInfo.getName()); - ldr.loadPaths(); - Archive a = null; - if (p.isComplete()) { - a = ldr.getArchive(); - a.verifyIntegrity(input); - } - Installer inst = new Installer(feedback, - input.getFileOperations(), - partialInfo, input.getLocalRegistry(), - input.getRegistry(), a); - inst.setPermissions(ldr.loadPermissions()); - inst.setSymlinks(ldr.loadSymlinks()); - configureInstaller(inst); - return inst; - - } - - CommandInput getInput() { - return input; - } - - Feedback getFeedback() { - return feedback; - } - - protected Map> getLicensesToAccept() { - return licensesToAccept; - } - - protected LicensePresenter createLicensePresenter() { - return new LicensePresenter(feedback, input.getLocalRegistry(), licensesToAccept); - } - - /** - * Forces the user to accept the licenses. - * - * @throws IOException - */ - void acceptLicenses() throws IOException { - if (licensesToAccept.isEmpty()) { - return; - } - Set processed = new HashSet<>(licensesToAccept.keySet()); - createLicensePresenter().run(); - processed.removeAll(licensesToAccept.keySet()); - markLicensesProcessed(processed); - licensesToAccept.clear(); - } - - public Set getProcessedLicenses() { - return new HashSet<>(processedLicenses); - } - - public void markLicensesProcessed(Collection licenseIDs) { - processedLicenses.addAll(licenseIDs); - } - - public Set getUnresolvedDependencies() { - return Collections.unmodifiableSet(unresolvedDependencies); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Installer.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Installer.java deleted file mode 100644 index 85397748f7b3..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Installer.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.channels.ByteChannel; -import java.nio.file.Files; -import java.nio.file.LinkOption; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermission; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.Verifier; - -/** - * The working internals of the 'add' command. - */ -public class Installer extends AbstractInstaller { - private static final Logger LOG = Logger.getLogger(Installer.class.getName()); - - /** - * Default permisions for files that should have the permissions changed. - */ - private static final Set DEFAULT_CHANGE_PERMISSION = EnumSet.of( - PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, - PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_EXECUTE, - PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_EXECUTE); - - private final List filesToDelete = new ArrayList<>(); - private final List dirsToDelete = new ArrayList<>(); - - private boolean allowFilesInComponentDir; - /** - * Paths tracked by the component system. - */ - private final Set visitedPaths = new HashSet<>(); - - public Installer(Feedback feedback, FileOperations fileOps, ComponentInfo componentInfo, ComponentRegistry registry, ComponentCollection collection, Archive a) { - super(feedback, fileOps, componentInfo, registry, collection, a); - } - - public boolean isAllowFilesInComponentDir() { - return allowFilesInComponentDir; - } - - public void setAllowFilesInComponentDir(boolean allowFilesInComponentDir) { - this.allowFilesInComponentDir = allowFilesInComponentDir; - } - - @Override - public void revertInstall() { - if (isDryRun()) { - return; - } - LOG.fine("Reverting installation"); - for (Path p : filesToDelete) { - try { - LOG.log(Level.FINE, "Deleting: {0}", p); - feedback.verboseOutput("INSTALL_CleanupFile", p); - fileOps.deleteFile(p); - } catch (IOException ex) { - feedback.error("INSTALL_CannotCleanupFile", ex, p, ex.getLocalizedMessage()); - } - } - // reverse the contents of directories, last created first: - Collections.reverse(dirsToDelete); - for (Path p : dirsToDelete) { - try { - LOG.log(Level.FINE, "Deleting directory: {0}", p); - feedback.verboseOutput("INSTALL_CleanupDirectory", p); - fileOps.deleteFile(p); - } catch (IOException ex) { - feedback.error("INSTALL_CannotCleanupFile", ex, p, ex.getLocalizedMessage()); - } - } - } - - Path translateTargetPath(Archive.FileEntry entry) { - return translateTargetPath(entry.getName()); - } - - Path translateTargetPath(String n) { - return translateTargetPath(null, n); - } - - Path translateTargetPath(Path base, String n) { - Path rel; - // assert relative path - rel = SystemUtils.fromCommonRelative(base, n); - Path p = getInstallPath().resolve(rel).normalize(); - // confine into graalvm subdir - if (!p.startsWith(getInstallPath())) { - throw new IllegalStateException( - feedback.l10n("INSTALL_WriteOutsideGraalvm", p)); - } - return p; - } - - /** - * Validates requirements, decides whether to install. Returns false if the component should be - * skipped. - * - * @return true, if the component should be installed - * @throws IOException - */ - @Override - public boolean validateAll() throws IOException { - Verifier veri = validateRequirements(); - ComponentInfo existing = registry.findComponent(componentInfo.getId()); - if (existing != null) { - if (!veri.shouldInstall(componentInfo)) { - return false; - } - } - validateFiles(); - validateSymlinks(); - return true; - } - - @Override - public void validateFiles() throws IOException { - if (archive == null) { - throw new UnsupportedOperationException(); - } - for (Archive.FileEntry entry : archive) { - if (entry.getName().startsWith("META-INF")) { // NOI18N - continue; - } - feedback.verboseOutput("INSTALL_VerboseValidation", entry.getName()); - validateOneEntry(translateTargetPath(entry), entry); - } - } - - @Override - public void validateSymlinks() throws IOException { - Map processSymlinks = getSymlinks(); - for (String sl : processSymlinks.keySet()) { - Path target = fileOps.materialize(translateTargetPath(sl), true); - if (Files.exists(target, LinkOption.NOFOLLOW_LINKS)) { - checkLinkReplacement(target, - translateTargetPath(target, processSymlinks.get(sl))); - } - } - } - - boolean validateOneEntry(Path target, Archive.FileEntry entry) throws IOException { - if (entry.isDirectory()) { - // assert relative path - Path dirPath = fileOps.materialize(SystemUtils.resolveRelative(getInstallPath(), entry.getName()), false); - // confine into graalvm subdir - if (Files.exists(dirPath)) { - if (!Files.isDirectory(dirPath)) { - throw new IOException( - feedback.l10n("INSTALL_OverwriteWithDirectory", dirPath)); - } - } - return true; - } - Path mt = fileOps.materialize(target, false); - boolean existingFile = mt != null && Files.exists(mt, LinkOption.NOFOLLOW_LINKS); - if (existingFile) { - return checkFileReplacement(mt, entry); - } - return false; - } - - public void install() throws IOException { - assert archive != null : "Must first download / set jar file"; - installContent(); - installFinish(); - } - - void installContent() throws IOException { - if (archive == null) { - throw new UnsupportedOperationException(); - } - // unpack files - unpackFiles(); - archive.completeMetadata(componentInfo); - processPermissions(); - createSymlinks(); - - List ll = new ArrayList<>(getTrackedPaths()); - Collections.sort(ll); - // replace paths with the really tracked ones - componentInfo.setPaths(ll); - } - - void installFinish() throws IOException { - // installation succeeded, add to component registry - if (!isDryRun()) { - registry.addComponent(getComponentInfo()); - } - } - - void unpackFiles() throws IOException { - final String storagePrefix = CommonConstants.PATH_COMPONENT_STORAGE + "/"; // NOI18N - for (Archive.FileEntry entry : archive) { - String path = entry.getName(); - if (!allowFilesInComponentDir && path.startsWith(storagePrefix) && path.length() > storagePrefix.length()) { - // disallow to unpack files in the component database (but permit subdirs). Some - // tools may write there, but - // GU will manage the storage itself. - if (path.indexOf('/', storagePrefix.length()) == -1) { - continue; - } - } - installOneEntry(entry); - } - } - - void ensurePathExists(Path targetPath) throws IOException { - if (!visitedPaths.add(targetPath)) { - return; - } - Path parent = getInstallPath(); - if (!targetPath.normalize().startsWith(parent)) { - throw new IllegalStateException( - feedback.l10n("INSTALL_WriteOutsideGraalvm", targetPath)); - } - Path relative = getInstallPath().relativize(targetPath); - Path relativeSubpath; - int count = 0; - for (Path n : relative) { - count++; - relativeSubpath = relative.subpath(0, count); - Path dir = fileOps.materialize(parent.resolve(n), true); - String pathString = SystemUtils.toCommonPath(relativeSubpath) + "/"; // NOI18N - - // Need to track either directories, which do not exist (and will be created) - // AND directories created by other components. - if (!Files.exists(dir) || getComponentDirectories().contains(pathString)) { - feedback.verboseOutput("INSTALL_CreatingDirectory", dir); - dirsToDelete.add(dir); - // add the created directory to the installed file list - addTrackedPath(pathString); - if (!Files.exists(dir)) { - if (!isDryRun()) { - Files.createDirectory(dir); - } - } - } - parent = dir; - } - } - - Path installOneEntry(Archive.FileEntry entry) throws IOException { - if (entry.getName().startsWith("META-INF")) { // NOI18N - return null; - } - Path targetPath = translateTargetPath(entry); - boolean b = validateOneEntry(targetPath, entry); - if (entry.isDirectory()) { - ensurePathExists(targetPath); - return targetPath; - } else { - String eName = entry.getName(); - if (b) { - feedback.verboseOutput("INSTALL_SkipIdenticalFile", eName); - return targetPath; - } - return installOneFile(targetPath, entry); - } - } - - Path installOneFile(Path target, Archive.FileEntry entry) throws IOException { - // copy contents of the file - try (InputStream jarStream = archive.getInputStream(entry)) { - Path mt = fileOps.materialize(target, false); - Path mt2 = fileOps.materialize(target, true); - boolean existingFile = mt != null && Files.exists(mt, LinkOption.NOFOLLOW_LINKS); - String eName = entry.getName(); - if (existingFile) { - /* - * if (checkFileReplacement(target, entry)) { - * feedback.verboseOutput("INSTALL_SkipIdenticalFile", eName); return target; // - * same file, not replacing, skip to next file } - */ - feedback.verboseOutput("INSTALL_ReplacingFile", eName); - } else { - filesToDelete.add(mt2); - feedback.verboseOutput("INSTALL_InstallingFile", eName); - } - ensurePathExists(target.getParent()); - addTrackedPath(SystemUtils.toCommonPath(getInstallPath().relativize(target))); - if (!isDryRun()) { - fileOps.installFile(target, jarStream); - } - } - return target; - } - - @Override - public void processPermissions() throws IOException { - Map setPermissions = getPermissions(); - List paths = new ArrayList<>(setPermissions.keySet()); - Collections.sort(paths); - for (String s : paths) { - // assert relative path - Path target = getInstallPath().resolve(SystemUtils.fromCommonRelative(s)); - String permissionString = setPermissions.get(s); - Set perms; - if (permissionString != null && !"".equals(permissionString)) { - perms = PosixFilePermissions.fromString(permissionString); - } else { - perms = DEFAULT_CHANGE_PERMISSION; - } - if (Files.exists(target, LinkOption.NOFOLLOW_LINKS)) { - fileOps.setPermissions(target, perms); - } - } - } - - @Override - public void createSymlinks() throws IOException { - if (SystemUtils.isWindows()) { - return; - } - Map makeSymlinks = getSymlinks(); - List createdRelativeLinks = new ArrayList<>(); - try { - List paths = new ArrayList<>(makeSymlinks.keySet()); - Collections.sort(paths); - Path instDir = getInstallPath(); - for (String s : paths) { - // assert relative path - Path source = instDir.resolve(SystemUtils.fromCommonRelative(s)); - if (source == null) { - continue; - } - Path parent = source.getParent(); - if (parent == null) { - continue; - } - Path target = SystemUtils.fromCommonString(makeSymlinks.get(s)); - Path result = parent.resolve(target); - if (result == null) { - continue; - } - result = result.normalize(); - if (!result.startsWith(getInstallPath())) { - throw new IllegalStateException( - feedback.l10n("INSTALL_SymlinkOutsideGraalvm", source, result)); - } - ensurePathExists(source.getParent()); - createdRelativeLinks.add(s); - addTrackedPath(s); - // TODO: check if the symlink does not exist and if so, whether - // reads the same. Behaviour similar to file CRC check. - if (Files.exists(source, LinkOption.NOFOLLOW_LINKS)) { - if (checkLinkReplacement(source, target)) { - feedback.verboseOutput("INSTALL_SkipIdenticalFile", s); - filesToDelete.add(source); - continue; - } else { - feedback.verboseOutput("INSTALL_ReplacingFile", s); - Files.delete(source); - } - } - filesToDelete.add(source); - feedback.verboseOutput("INSTALL_CreatingSymlink", s, makeSymlinks.get(s)); - if (!isDryRun()) { - Files.createSymbolicLink(source, target); - } - } - } catch (UnsupportedOperationException ex) { - LOG.log(Level.INFO, "Symlinks not supported", ex); - } - componentInfo.addPaths(createdRelativeLinks); - } - - boolean checkLinkReplacement(Path existingPath, Path target) throws IOException { - boolean replace = isReplaceDiferentFiles(); - if (Files.exists(existingPath, LinkOption.NOFOLLOW_LINKS)) { - if (!Files.isSymbolicLink(existingPath)) { - if (Files.isRegularFile(existingPath) && replace) { - return false; - } - throw new IOException( - feedback.l10n("INSTALL_OverwriteWithLink", existingPath)); - } - } - Path p = Files.readSymbolicLink(existingPath); - if (!target.equals(p)) { - if (replace) { - return false; - } - throw feedback.failure("INSTALL_ReplacedFileDiffers", null, existingPath); - } - return true; - } - - boolean checkFileReplacement(Path existingPath, Archive.FileEntry entry) throws IOException { - boolean replace = isReplaceDiferentFiles(); - if (Files.isDirectory(existingPath)) { - throw new IOException( - feedback.l10n("INSTALL_OverwriteWithFile", existingPath)); - } - if (!Files.isRegularFile(existingPath) || (Files.size(existingPath) != entry.getSize())) { - if (replace) { - return false; - } - throw feedback.failure("INSTALL_ReplacedFileDiffers", null, existingPath); - } - try (ByteChannel is = Files.newByteChannel(existingPath)) { - if (!archive.checkContentsMatches(is, entry)) { - if (replace) { - return false; - } - throw feedback.failure("INSTALL_ReplacedFileDiffers", null, existingPath); - } - } - return true; - } - - @Override - public String toString() { - return "Installer[" + componentInfo.getId() + ":" + componentInfo.getName() + "=" + componentInfo.getVersion().displayString() + "]"; // NOI18N - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/LicensePresenter.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/LicensePresenter.java deleted file mode 100644 index ec9cca131e39..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/LicensePresenter.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.UserAbortException; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * License console "dialog" driver. - * - * @author sdedic - */ -public class LicensePresenter { - private final Feedback feedback; - private final ComponentRegistry localRegistry; - - /** - * Licenses to be processed. - */ - private final Map> licensesToAccept; - - private State state = State.NONE; - - /** - * True, if multiple licenses were present initially. - */ - private boolean multiLicenses; - - /** - * The ID (hash) of the license to be displayed. - */ - private String displayLicenseId; - - enum State { - /** - * List of licenses with choice to display some or accept all. - */ - LIST, - - /** - * Accepts the input. - */ - LISTINPUT, - - /** - * Single license prompt. - */ - SINGLE, - - /** - * Display a license, confirm it. - */ - LICENSE, - - /** - * Abort. - */ - NONE - } - - public LicensePresenter(Feedback feedback, ComponentRegistry localRegistry, Map> licenseIDs) { - this.feedback = feedback.withBundle(LicensePresenter.class); - this.localRegistry = localRegistry; - this.licensesToAccept = licenseIDs; - } - - public Map> getLicensesToAccept() { - return licensesToAccept; - } - - public void filterAcceptedLicenses() { - for (String licId : new ArrayList<>(licensesToAccept.keySet())) { - Collection loaders = licensesToAccept.get(licId); - for (MetadataLoader ldr : new ArrayList<>(loaders)) { - ComponentInfo ci = ldr.getComponentInfo(); - // query the metadata loader (possibly delegates to original software channel - // provider). - Date accepted = ldr.isLicenseAccepted(ci, licId); - if (accepted == null) { - accepted = localRegistry.isLicenseAccepted(ci, licId); - } - if (accepted != null) { - feedback.verboseOutput("INSTALL_LicenseAcceptedAt", ldr.getLicenseType(), accepted, ci.getId(), ci.getName()); - loaders.remove(ldr); - } - } - if (loaders.isEmpty()) { - licensesToAccept.remove(licId); - } - } - multiLicenses = licensesToAccept.size() > 1; - } - - public State getState() { - return state; - } - - public boolean isMultiLicenses() { - return multiLicenses; - } - - public String getDisplayLicenseId() { - return displayLicenseId; - } - - String formatComponentList(String licId) { - List loaders = licensesToAccept.get(licId); - String list = null; - for (MetadataLoader l : loaders) { - ComponentInfo ci = l.getComponentInfo(); - if (list == null) { - list = feedback.l10n("INSTALL_LicenseComponentStart", ci.getName()); - } else { - list = feedback.l10n("INSTALL_LicenseComponentCont", list, ci.getName()); - } - } - return list; - } - - void displayLicenseList() { - feedback.output("INSTALL_LicensesToAccept"); - int idx = 1; - for (String licId : licensesToAccept.keySet()) { - List loaders = licensesToAccept.get(licId); - String list = formatComponentList(licId); - feedback.output("INSTALL_AcceptLicenseComponents", loaders.get(0).getLicenseType(), list, idx); - idx++; - } - feedback.outputPart("INSTALL_AcceptAllLicensesPrompt"); - state = State.LISTINPUT; - } - - private static final Pattern ALL_NUMBERS = Pattern.compile("[0-9]+"); - - boolean isFinished() { - return licensesToAccept.isEmpty(); - } - - void acceptAllLicenses() { - for (String s : new ArrayList<>(licensesToAccept.keySet())) { - acceptLicense(s); - } - licensesToAccept.clear(); - } - - boolean isYes(String userInput) { - if (userInput == Feedback.AUTO_YES) { - return true; - } - Pattern p = Pattern.compile(feedback.l10n("INSTALL_AcceptPromptResponseYes@"), Pattern.CASE_INSENSITIVE); - return p.matcher(userInput).matches(); - } - - boolean isRead(String userInput) { - Pattern p = Pattern.compile(feedback.l10n("INSTALL_AcceptPromptResponseRead@"), Pattern.CASE_INSENSITIVE); - return p.matcher(userInput).matches(); - } - - int processUserInputForList() { - String userInput = feedback.acceptLine(true); - Pattern p = Pattern.compile(feedback.l10n("INSTALL_AcceptPromptResponseAbort@"), Pattern.CASE_INSENSITIVE); - if (p.matcher(userInput).matches()) { - throw new UserAbortException(); - } - if (isYes(userInput)) { - acceptAllLicenses(); - state = State.NONE; - return 0; - } - - if (!ALL_NUMBERS.matcher(userInput).matches()) { - feedback.output("INSTALL_LicenseNumberInvalidEntry", licensesToAccept.size()); - return -1; - } - int n = Integer.parseInt(userInput); - if (n < 0 || n > licensesToAccept.size()) { - feedback.output("INSTALL_LicenseNumberOutOfRange", licensesToAccept.size()); - return -1; - } - return n; - } - - protected void acceptLicense(String licenseId) { - String licText; - try { - licText = loadLicenseText(licenseId); - } catch (IOException ex) { - throw feedback.failure("INSTALL_ErrorHandlingLicenses", ex, ex.getLocalizedMessage()); - } - for (MetadataLoader ldr : licensesToAccept.get(licenseId)) { - Boolean result = null; - try { - // first ask the metadata loader delegate. - result = ldr.recordLicenseAccepted(ldr.getComponentInfo(), licenseId, licText, null); - } catch (IOException ex) { - feedback.error("WARN_LicenseNotRecorded", ex, licenseId, ex.getLocalizedMessage()); - } - if (result == null) { - localRegistry.acceptLicense(ldr.getComponentInfo(), licenseId, licText); - } - } - licensesToAccept.remove(licenseId); - } - - void displaySingleLicense() { - String licId = licensesToAccept.keySet().iterator().next(); - MetadataLoader ldr = licensesToAccept.get(licId).get(0); - String type = ldr.getLicenseType(); - String compList = formatComponentList(licId); - feedback.output("INSTALL_AcceptLicense", compList, type); - feedback.outputPart("INSTALL_AcceptSingleLicense"); - String input = feedback.acceptLine(true); - - if (isYes(input)) { - acceptLicense(licId); - return; - } else if (isRead(input)) { - displayLicenseId = licId; - state = State.LICENSE; - } else { - throw new UserAbortException(); - } - } - - void displayLicenseText() throws IOException { - String text = loadLicenseText(displayLicenseId); - feedback.verbatimOut(text, false); - feedback.output("INSTALL_AcceptLicensePrompt"); - String input = feedback.acceptLine(true); - - if (isYes(input)) { - acceptLicense(displayLicenseId); - state = multiLicenses ? State.LIST : State.SINGLE; - } else if (!multiLicenses) { - throw new UserAbortException(); - } else { - state = State.LIST; - } - } - - boolean isLicenseRemote(String licenseId) { - MetadataLoader ldr = licensesToAccept.get(licenseId).get(0); - String licPath = ldr.getLicensePath(); - return SystemUtils.isRemotePath(licPath); // NOI18N - } - - /** - * Loads license text from the archive. - * - * @param licenseId - * @return text of the license - * @throws IOException - */ - String loadLicenseText(String licenseId) throws IOException { - MetadataLoader ldr = licensesToAccept.get(licenseId).get(0); - if (isLicenseRemote(licenseId)) { - return downloadLicenseText(licenseId, ldr); - } else { - return loadFileLicenseText(ldr); - } - } - - private Map remoteLicenseContents = new HashMap<>(); - - String downloadLicenseText(String id, MetadataLoader ldr) throws IOException { - String c = remoteLicenseContents.get(id); - if (c != null) { - return c; - } - String t = ldr.getLicenseType(); - String label; - - if (!t.equals(ldr.getLicensePath())) { - label = feedback.l10n("INSTALL_DownloadLicenseName", t); - } else { - label = feedback.l10n("INSTALL_DownloadLicenseFile"); - } - c = String.join("\n", Files.readAllLines( - downloadLicenseText(label, ldr.getLicensePath()).toPath())); // NOI18N - remoteLicenseContents.put(id, c); - return c; - } - - File downloadLicenseText(String label, String url) throws IOException { - FileDownloader dn = new FileDownloader( - label, - SystemUtils.toURL(url), - feedback); - - dn.download(); - return dn.getLocalFile(); - } - - String loadFileLicenseText(MetadataLoader ldr) throws IOException { - // may require a download of the archive - try (Archive a = ldr.getArchive()) { - String licensePath = ldr.getLicensePath(); - Archive.FileEntry licenseEntry = null; - - for (Archive.FileEntry e : a) { - String n = e.getName(); - if (n.startsWith("/")) { - n = n.substring(1); - } else if (n.startsWith("./")) { - n = n.substring(2); - } - if (n.equals(licensePath)) { - licenseEntry = e; - break; - } - } - - if (licenseEntry == null) { - throw new IOException(feedback.l10n("INSTALL_LicenseNotFound", licensePath)); - } - - try (InputStream es = a.getInputStream(licenseEntry); - InputStreamReader esr = new InputStreamReader(es, "UTF-8"); - BufferedReader buf = new BufferedReader(esr)) { - return buf.lines().collect(Collectors.joining("\n")); // NOI18N - } - } - } - - void init() { - filterAcceptedLicenses(); - state = multiLicenses ? State.LIST : State.SINGLE; - } - - void run() { - init(); - try { - while (!isFinished()) { - singleStep(); - } - } catch (IOException ex) { - throw feedback.failure("INSTALL_ErrorHandlingLicenses", ex, ex.getLocalizedMessage()); - } - } - - void singleStep() throws IOException { - switch (state) { - case LISTINPUT: - int choice = processUserInputForList(); - switch (choice) { - case -1: - break; - case 0: - state = State.NONE; - break; - default: - List ids = new ArrayList<>(licensesToAccept.keySet()); - displayLicenseId = ids.get(choice - 1); - state = State.LICENSE; - } - break; - case SINGLE: - displaySingleLicense(); - break; - case LICENSE: - displayLicenseText(); - break; - case NONE: - break; - case LIST: - displayLicenseList(); - break; - default: - throw new AssertionError(state.name()); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/ListInstalledCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/ListInstalledCommand.java deleted file mode 100644 index cdc4161fcbef..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/ListInstalledCommand.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * Command to lists installed components. - */ -public class ListInstalledCommand extends QueryCommandBase { - private List expressions = Collections.emptyList(); - private Pattern filterPattern; - - public List getExpressions() { - return expressions; - } - - public void setExpressions(List expressions) { - this.expressions = expressions; - } - - @Override - public Map supportedOptions() { - Map m = new HashMap<>(super.supportedOptions()); - m.put(Commands.OPTION_CATALOG, ""); - m.put(Commands.LONG_OPTION_CATALOG, Commands.OPTION_CATALOG); - - m.put(Commands.OPTION_URLS, "X"); // mask out - m.put(Commands.OPTION_FILES, "X"); // mask out - return m; - } - - private void makeRegularExpression() { - StringBuilder sb = new StringBuilder(); - for (String s : expressions) { - if (sb.length() > 0) { - sb.append("|"); - } - sb.append(Pattern.quote(s)).append("$"); - } - if (sb.length() == 0) { - sb.append(".*"); - } - filterPattern = Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE); - } - - List findComponentIds() { - Collection comps = catalog.getComponentIDs(); - List ids = new ArrayList<>(comps.size()); - for (String s : comps) { - if (filterPattern.matcher(s).find()) { - ids.add(s); - } - } - Collections.sort(ids); - return ids; - } - - protected String acceptExpression(String expr) { - return expr; - } - - @Override - public int execute() throws IOException { - if (input.optValue(Commands.OPTION_HELP) != null) { - feedback.output("LIST_Help"); - return 0; - } - init(input, feedback); - expressions = new ArrayList<>(); - while (input.hasParameter()) { - String s = input.nextParameter(); - if (s == null || s.isEmpty()) { - continue; - } - String accepted = acceptExpression(s); - if (accepted != null) { - expressions.add(accepted); - } - } - if (process() || isJson()) { - printComponents(); - } - return 0; - } - - protected Version.Match getVersionFilter() { - return input.getLocalRegistry().getGraalVersion().match(Version.Match.Type.INSTALLABLE); - } - - protected List filterDisplayedVersions(@SuppressWarnings("unused") String id, Collection infos) { - List ordered = new ArrayList<>(infos); - Collections.sort(ordered, ComponentInfo.reverseVersionComparator(input.getLocalRegistry().getManagementStorage())); - return ordered; - } - - boolean process() { - makeRegularExpression(); - List ids = findComponentIds(); - List exceptions = new ArrayList<>(); - if (ids.isEmpty()) { - if (!simpleFormat) { - feedback.message("LIST_NoComponentsFound"); - } - return false; - } - Version.Match versionFilter = getVersionFilter(); - for (String id : ids) { - try { - List infos = new ArrayList<>(catalog.loadComponents(id, versionFilter, listFiles)); - if (infos != null) { - for (ComponentInfo ci : filterDisplayedVersions(id, infos)) { - addComponent(null, ci); - } - } - } catch (MetadataException ex) { - exceptions.add(ex); - } - } - if (components.isEmpty()) { - if (!simpleFormat) { - feedback.message("LIST_NoComponentsFound"); - } - return false; - } - if (!simpleFormat && !exceptions.isEmpty()) { - feedback.error("LIST_ErrorInComponentMetadata", null); - for (Exception e : exceptions) { - feedback.error("LIST_ErrorInComponentMetadataItem", e, e.getLocalizedMessage()); - } - } - return true; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstCommand.java deleted file mode 100644 index 0cdec4fe59a4..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstCommand.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * - * @author sdedic - */ -public class PostInstCommand implements InstallerCommand { - private CommandInput input; - private Feedback feedback; - - @Override - public Map supportedOptions() { - return Collections.emptyMap(); - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.input = commandInput; - this.feedback = feedBack; - } - - @Override - public int execute() throws IOException { - String compId; - PostInstProcess pp = new PostInstProcess(input, feedback); - while ((compId = input.nextParameter()) != null) { - ComponentInfo info = input.getLocalRegistry().loadSingleComponent(compId.toLowerCase(), true); - if (info != null) { - pp.addComponentInfo(info); - } - } - - pp.run(); - return 0; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstProcess.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstProcess.java deleted file mode 100644 index df316caec365..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PostInstProcess.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * - * @author sdedic - */ -final class PostInstProcess { - private final CommandInput input; - private final Feedback feedback; - private final List infos = new ArrayList<>(); - - PostInstProcess(CommandInput cInput, Feedback fb) { - this.input = cInput; - this.feedback = fb; - } - - public void addComponentInfo(ComponentInfo info) { - this.infos.add(info); - } - - private static final Pattern TOKEN_PATTERN = Pattern.compile("\\$\\{([\\p{Alnum}_-]+)\\}"); - - String replaceTokens(ComponentInfo info, String message) { - Map tokens = new HashMap<>(); - Path graalPath = input.getGraalHomePath().normalize(); - - Path archPath = SystemUtils.getRuntimeLibDir(graalPath, true); - - tokens.put(CommonConstants.TOKEN_GRAALVM_PATH, graalPath.toString()); - tokens.put(CommonConstants.TOKEN_GRAALVM_LANG_DIR, SystemUtils.getRuntimeBaseDir(graalPath).resolve("languages").toString()); // NOI18N - tokens.put(CommonConstants.TOKEN_GRAALVM_RTLIB_ARCH_DIR, archPath.toString()); - tokens.put(CommonConstants.TOKEN_GRAALVM_RTLIB_DIR, SystemUtils.getRuntimeLibDir(graalPath, false).toString()); - - tokens.putAll(info.getRequiredGraalValues()); - tokens.putAll(input.getLocalRegistry().getGraalCapabilities()); - - Matcher m = TOKEN_PATTERN.matcher(message); - StringBuilder result = null; - int start = 0; - int last = 0; - while (m.find(start)) { - String token = m.group(1); - String val = tokens.get(token); - if (val != null) { - if (result == null) { - result = new StringBuilder(archPath.toString().length() * 2); - } - result.append(message.substring(last, m.start())); - result.append(val); - last = m.end(); - } - start = m.end(); - } - - if (result == null) { - return message; - } else { - result.append(message.substring(last)); - return result.toString(); - } - } - - void run() { - for (ComponentInfo ci : infos) { - printPostinst(ci); - } - } - - void printPostinst(ComponentInfo i) { - String msg = i.getPostinstMessage(); - if (msg != null) { - String replaced = replaceTokens(i, msg); - // replace potential fileName etc - feedback.verbatimOut(replaced, false); - // add some newlines - feedback.verbatimOut("", false); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveCommand.java deleted file mode 100644 index 68db9ea4bfad..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveCommand.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * - * @author sdedic - */ -public class PreRemoveCommand implements InstallerCommand { - private CommandInput input; - private Feedback feedback; - - @Override - public Map supportedOptions() { - return Collections.emptyMap(); - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.input = commandInput; - this.feedback = feedBack; - } - - @Override - public int execute() throws IOException { - String compId; - PreRemoveProcess pp = new PreRemoveProcess(input.getGraalHomePath(), input.getFileOperations(), feedback); - while ((compId = input.nextParameter()) != null) { - ComponentInfo info = input.getLocalRegistry().loadSingleComponent(compId.toLowerCase(), true); - if (info != null) { - pp.addComponentInfo(info); - } - } - - pp.run(); - return 0; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveProcess.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveProcess.java deleted file mode 100644 index 35f135ebd36a..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/PreRemoveProcess.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; - -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * - * @author sdedic - */ -public class PreRemoveProcess { - private final Path installPath; - private final Feedback feedback; - private final List infos = new ArrayList<>(); - private final FileOperations fileOps; - - private boolean dryRun; - private boolean ignoreFailedDeletions; - private Set knownPaths; - - public PreRemoveProcess(Path instPath, FileOperations fops, Feedback fb) { - this.feedback = fb.withBundle(PreRemoveProcess.class); - installPath = instPath; - fileOps = fops; - } - - public boolean isDryRun() { - return dryRun; - } - - public PreRemoveProcess setDryRun(boolean dryRun) { - this.dryRun = dryRun; - return this; - } - - public boolean isIgnoreFailedDeletions() { - return ignoreFailedDeletions; - } - - public PreRemoveProcess setIgnoreFailedDeletions(boolean ignoreFailedDeletions) { - this.ignoreFailedDeletions = ignoreFailedDeletions; - return this; - } - - public void addComponentInfo(ComponentInfo info) { - this.infos.add(info); - } - - /** - * Process all the components, prints message. - * - * @throws IOException if deletion fails - */ - public void run() throws IOException { - for (ComponentInfo ci : infos) { - processComponent(ci); - } - } - - /** - * Called also from Uninstaller. Will delete one single file, possibly with altering permissions - * on the parent so the file can be deleted. - * - * @param p file to delete - * @throws IOException - */ - void deleteOneFile(Path p) throws IOException { - try { - fileOps.deleteFile(p); - } catch (IOException ex) { - if (ignoreFailedDeletions) { - if (Files.isDirectory(p)) { - feedback.error("INSTALL_FailedToDeleteDirectory", ex, p, ex.getLocalizedMessage()); - } else { - feedback.error("INSTALL_FailedToDeleteFile", ex, p, ex.getLocalizedMessage()); - } - return; - } - throw ex; - // throw new UncheckedIOException(ex); - } - } - - /** - * Also called from Uninstaller. - * - * @param rootPath root path to delete (inclusive) - * @throws IOException if the deletion fails. - */ - void deleteContentsRecursively(Path rootPath) throws IOException { - if (dryRun) { - return; - } - try (Stream paths = Files.walk(rootPath)) { - paths.sorted(Comparator.reverseOrder()).forEach((p) -> { - try { - if (!p.equals(rootPath) && shouldDeletePath(p)) { - deleteOneFile(p); - } - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }); - } catch (UncheckedIOException ex) { - throw ex.getCause(); - } - } - - private boolean shouldDeletePath(Path toDelete) { - Path rel; - try { - rel = installPath.relativize(toDelete); - } catch (IllegalArgumentException ex) { - // cannot relativize; avoid to delete such thing. - return false; - } - String relString = SystemUtils.toCommonPath(rel); - if (Files.isDirectory(toDelete)) { - relString += "/"; // NOI18N - } - return knownPaths == null || !knownPaths.contains(relString); - } - - void processComponent(ComponentInfo ci) throws IOException { - for (String s : ci.getWorkingDirectories()) { - Path p = installPath.resolve(SystemUtils.fromCommonRelative(s)); - feedback.verboseOutput("UNINSTALL_DeletingDirectoryRecursively", p); - this.knownPaths = new HashSet<>(ci.getPaths()); - deleteContentsRecursively(p); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/QueryCommandBase.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/QueryCommandBase.java deleted file mode 100644 index e3a1ed44a1f0..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/QueryCommandBase.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.File; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import static org.graalvm.component.installer.Commands.LONG_OPTION_LIST_FILES; -import static org.graalvm.component.installer.Commands.OPTION_LIST_FILES; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.CAP_GRAALVM_VERSION; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONObject; - -import static org.graalvm.component.installer.Commands.OPTION_JSON_OUTPUT; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENTS; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_GRAALVM; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_ID; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_NAME; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_ORIGIN; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_STABILITY; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_VERSION; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_FILES; -import static org.graalvm.component.installer.CommonConstants.JSON_KEY_COMPONENT_LIC_IMPL_ACCEPT; - -/** - * List command. - */ -public abstract class QueryCommandBase implements InstallerCommand { - - protected static final Map BASE_OPTIONS = new HashMap<>(); - - static { - BASE_OPTIONS.put(OPTION_LIST_FILES, ""); // NOI18N - BASE_OPTIONS.put(LONG_OPTION_LIST_FILES, OPTION_LIST_FILES); // NOI18N - - BASE_OPTIONS.put(Commands.OPTION_JSON_OUTPUT, ""); - BASE_OPTIONS.put(Commands.LONG_OPTION_JSON_OUTPUT, Commands.OPTION_JSON_OUTPUT); - } - - @Override - public Map supportedOptions() { - return BASE_OPTIONS; - } - - protected CommandInput input; - protected ComponentRegistry registry; - protected ComponentCollection catalog; - protected Feedback feedback; - protected boolean verbose; - protected boolean printTable; - protected boolean listFiles; - private boolean isJson; - protected List componentParams = new ArrayList<>(); - protected List components = new ArrayList<>(); - protected boolean simpleFormat; - - private JSONObject jsonComponent; - - protected JSONObject getJSONComponent() { - return jsonComponent; - } - - public ComponentRegistry getRegistry() { - return registry; - } - - protected boolean isJson() { - return isJson; - } - - public void setRegistry(ComponentRegistry registry) { - this.registry = registry; - } - - public Feedback getFeedback() { - return feedback; - } - - public void setFeedback(Feedback feedback) { - this.feedback = feedback; - } - - public boolean isListFiles() { - return listFiles; - } - - public void setListFiles(boolean listFiles) { - this.listFiles = listFiles; - } - - public boolean isVerbose() { - return verbose; - } - - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } - - protected ComponentCollection initRegistry() { - this.registry = input.getLocalRegistry(); - if (input.optValue(Commands.OPTION_CATALOG) != null || input.optValue(Commands.OPTION_FOREIGN_CATALOG) != null) { - return input.getRegistry(); - } else { - return registry; - } - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.input = commandInput; - this.catalog = initRegistry(); - this.feedback = feedBack; - this.isJson = commandInput.optValue(OPTION_JSON_OUTPUT) != null; - this.feedback.setSilent(isJson); - listFiles = commandInput.optValue(OPTION_LIST_FILES) != null; - verbose = commandInput.optValue(Commands.OPTION_VERBOSE) != null; - printTable = !listFiles && !verbose; - processOutputFormat(); - } - - protected void addComponent(ComponentParam param, ComponentInfo info) { - componentParams.add(param); - components.add(info); - } - - public List getComponents() { - return components; - } - - protected void printComponents() { - printHeader(); - JSONArray jsonComponents = null; - if (isJson) { - assert jsonComponent == null; - jsonComponents = new JSONArray(); - } - Iterator itpar = componentParams.iterator(); - for (ComponentInfo info : components) { - if (jsonComponents != null) { - jsonComponents.put(jsonComponent = new JSONObject()); - } - printDetails(itpar.next(), info); - printFileList(info); - printSeparator(info); - } - if (jsonComponents != null) { - final JSONObject json = new JSONObject().put(JSON_KEY_COMPONENTS, jsonComponents); - feedback.suppressSilent(() -> feedback.verbatimOut(verbose ? json.toString(2) : json.toString(), false)); - jsonComponent = null; - } - } - - void printHeader() { - if (simpleFormat) { - feedback.output("LIST_ComponentShortListHeader_Simple@"); - return; - } - if (printTable) { - feedback.output("LIST_ComponentShortListHeader"); - } - } - - String val(String s) { - if (simpleFormat) { - return s == null ? "" : s; - } else { - return s == null ? feedback.l10n("LIST_MetadataUnknown") : s; - } - } - - protected String shortenComponentId(ComponentInfo info) { - return registry.shortenComponentId(info); - } - - @SuppressWarnings("unused") - void printDetails(ComponentParam param, ComponentInfo info) { - String org; - URL u = info.getRemoteURL(); - if (simpleFormat) { - org = u == null ? "" : u.toString(); - } else if (u == null) { - org = ""; // NOI18N - } else if (u.getProtocol().equals("file")) { // NOI18N - try { - org = new File(u.toURI()).getAbsolutePath(); - } catch (URISyntaxException ex) { - // should not happen - org = u.toString(); - } - } else { - org = u.getHost(); - } - boolean implicitlyAccepted = info.isImplicitlyAccepted(); - if (isJson) { - jsonComponent.put(JSON_KEY_COMPONENT_ID, shortenComponentId(info)); - jsonComponent.put(JSON_KEY_COMPONENT_VERSION, info.getVersion().displayString()); - jsonComponent.put(JSON_KEY_COMPONENT_NAME, info.getName()); - jsonComponent.put(JSON_KEY_COMPONENT_GRAALVM, findRequiredGraalVMVersion(info)); - jsonComponent.put(JSON_KEY_COMPONENT_STABILITY, info.getStability().displayName(feedback)); - jsonComponent.put(JSON_KEY_COMPONENT_ORIGIN, u == null ? "" : u); - jsonComponent.put(JSON_KEY_COMPONENT_LIC_IMPL_ACCEPT, implicitlyAccepted); - } else if (printTable) { - String fmt = simpleFormat ? "LIST_ComponentShortList_Simple@" : "LIST_ComponentShortList"; - String line = String.format(feedback.l10n(fmt), - shortenComponentId(info), info.getVersion().displayString(), info.getName(), org, info.getId(), info.getStability().displayName(feedback), - implicitlyAccepted); - feedback.verbatimOut(line, false); - } else { - String fmt = simpleFormat ? "LIST_ComponentBasicInfo_Simple@" : "LIST_ComponentBasicInfo"; - feedback.output(fmt, - shortenComponentId(info), info.getVersion().displayString(), info.getName(), - findRequiredGraalVMVersion(info), u == null ? "" : u, info.getId(), info.getStability().displayName(feedback), implicitlyAccepted); - } - } - - protected String findRequiredGraalVMVersion(ComponentInfo info) { - String s = info.getRequiredGraalValues().get(CAP_GRAALVM_VERSION); - if (s == null) { - return val(s); - } - Version v = Version.fromString(s); - return v.displayString(); - } - - void printFileList(ComponentInfo info) { - if (!listFiles) { - return; - } - List files = new ArrayList<>(info.getPaths()); - Collections.sort(files); - if (isJson) { - jsonComponent.put(JSON_KEY_COMPONENT_FILES, files); - } else { - feedback.output(simpleFormat ? "LIST_ComponentFilesHeader_Simple@" : "LIST_ComponentFilesHeader", files.size()); - for (String s : files) { - feedback.verbatimOut(s, false); - } - if (simpleFormat) { - feedback.output("LIST_ComponentFilesEnd@"); - } - } - } - - void printSeparator(@SuppressWarnings("unused") ComponentInfo info) { - if (simpleFormat || printTable || isJson) { - return; - } - feedback.verbatimOut("", true); // NOI18N - } - - void processOutputFormat() { - if (Boolean.TRUE.toString().equals(System.getProperty(CommonConstants.SYSPROP_SIMPLE_OUTPUT))) { - simpleFormat = true; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/RebuildImageCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/RebuildImageCommand.java deleted file mode 100644 index 5eb823665cd5..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/RebuildImageCommand.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.ProcessBuilder.Redirect; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import static org.graalvm.component.installer.Commands.DO_NOT_PROCESS_OPTIONS; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.SystemUtils; - -public class RebuildImageCommand implements InstallerCommand { - private static final Map OPTIONS = new HashMap<>(); - - private Feedback feedback; - private CommandInput input; - - static { - OPTIONS.put(DO_NOT_PROCESS_OPTIONS, ""); - } - - @Override - public Map supportedOptions() { - return OPTIONS; - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.feedback = feedBack; - this.input = commandInput; - } - - final class OutputRewriter implements Runnable { - private final String processName; - private final String substProcessName; - private final InputStream output; - private volatile IOException terminated; - - OutputRewriter(InputStream output, String processName, String substProcessName) { - this.output = output; - this.processName = processName; - this.substProcessName = substProcessName; - } - - @Override - public void run() { - try (BufferedReader bre = new BufferedReader(new InputStreamReader(output))) { - String line; - while ((line = bre.readLine()) != null) { - int i = line.indexOf(processName); - if (i != -1) { - line = line.substring(0, i) + substProcessName + - line.substring(i + processName.length()); - } - feedback.verbatimOut(line, false); - } - } catch (IOException ex) { - terminated = ex; - } - } - } - - @Override - public int execute() throws IOException { - input.getLocalRegistry().verifyAdministratorAccess(); - - ProcessBuilder pb = new ProcessBuilder(); - List commandLine = new ArrayList<>(); - // enforce relative path - Path toolPath = findNativeImagePath(input, feedback); - if (toolPath == null) { - feedback.error("REBUILD_RebuildImagesNotInstalled", null, CommonConstants.NATIVE_IMAGE_ID); - return 2; - } - String procName = toolPath.toAbsolutePath().toString(); - commandLine.add(procName); - if (input.optValue(Commands.OPTION_VERBOSE) != null) { - commandLine.add("--verbose"); // NOI18N - } - while (input.hasParameter()) { - commandLine.add(input.nextParameter()); - } - - pb.command(commandLine); - pb.directory(input.getGraalHomePath().toFile()); - pb.redirectInput(Redirect.INHERIT); - pb.redirectError(Redirect.INHERIT); - - ExecutorService connectors = Executors.newCachedThreadPool(); - try { - int exitCode; - Process p = pb.start(); - OutputRewriter rw = new OutputRewriter(p.getInputStream(), procName, - feedback.l10n("REBUILD_RewriteRebuildToolName")); // NOI18N - Future ioWriter = connectors.submit(rw); - exitCode = p.waitFor(); - ioWriter.get(1000, TimeUnit.MILLISECONDS); - if (rw.terminated != null) { - feedback.error("REBUILD_ImageToolInterrupted", rw.terminated); - } - return exitCode; - } catch (ExecutionException ex) { - feedback.error("REBUILD_ErrorCommunicatingImageTool", ex, ex.getLocalizedMessage()); - return 3; - } catch (TimeoutException | InterruptedException ex) { - feedback.error("REBUILD_ImageToolInterrupted", ex); - return 1; - } - } - - public static Path findNativeImagePath(CommandInput input, Feedback feedback) { - Path baseDir = SystemUtils.getRuntimeBaseDir(input.getGraalHomePath()); - String toolRelativePath = feedback.l10n("REBUILD_ToolRelativePath"); - if (SystemUtils.isWindows()) { - toolRelativePath += ".cmd"; - } - Path p = baseDir.resolve(SystemUtils.fromCommonString(toolRelativePath)); - return (Files.isReadable(p) || Files.isExecutable(p)) ? p : null; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UninstallCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UninstallCommand.java deleted file mode 100644 index a006b4f93240..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UninstallCommand.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; - -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.DistributionType; - -public class UninstallCommand implements InstallerCommand { - - static final Map OPTIONS = new HashMap<>(); - - static { - OPTIONS.put(Commands.OPTION_DRY_RUN, ""); - OPTIONS.put(Commands.OPTION_FORCE, ""); - OPTIONS.put(Commands.OPTION_IGNORE_FAILURES, ""); - OPTIONS.put(Commands.OPTION_UNINSTALL_DEPENDENT, ""); - OPTIONS.put(Commands.OPTION_NO_DEPENDENCIES, ""); - - OPTIONS.put(Commands.LONG_OPTION_DRY_RUN, Commands.OPTION_DRY_RUN); - OPTIONS.put(Commands.LONG_OPTION_FORCE, Commands.OPTION_FORCE); - OPTIONS.put(Commands.LONG_OPTION_IGNORE_FAILURES, Commands.OPTION_IGNORE_FAILURES); - OPTIONS.put(Commands.LONG_OPTION_UNINSTALL_DEPENDENT, Commands.OPTION_UNINSTALL_DEPENDENT); - OPTIONS.put(Commands.LONG_OPTION_NO_DEPENDENCIES, Commands.OPTION_NO_DEPENDENCIES); - } - - private final Map toUninstall = new LinkedHashMap<>(); - private List uninstallSequence = new ArrayList<>(); - private Feedback feedback; - private CommandInput input; - private boolean ignoreFailures; - private ComponentRegistry registry; - private boolean removeDependent; - private boolean breakDependent; - private Map> brokenDependencies = new HashMap<>(); - - @Override - public Map supportedOptions() { - return OPTIONS; - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.input = commandInput; - this.feedback = feedBack; - this.registry = input.getLocalRegistry(); - setIgnoreFailures(input.optValue(Commands.OPTION_FORCE) != null); - setBreakDependent(input.optValue(Commands.OPTION_FORCE) != null); - setRemoveDependent(input.optValue(Commands.OPTION_UNINSTALL_DEPENDENT) != null); - } - - public boolean isIgnoreFailures() { - return ignoreFailures; - } - - public void setIgnoreFailures(boolean ignoreFailures) { - this.ignoreFailures = ignoreFailures; - } - - public boolean isRemoveDependent() { - return removeDependent; - } - - public void setRemoveDependent(boolean removeDependent) { - this.removeDependent = removeDependent; - } - - public boolean isBreakDependent() { - return breakDependent; - } - - public void setBreakDependent(boolean breakDependent) { - this.breakDependent = breakDependent; - } - - public Collection getUninstallComponents() { - return new ArrayList<>(toUninstall.values()); - } - - public List getUninstallSequence() { - return Collections.unmodifiableList(uninstallSequence); - } - - public Map> getBrokenDependencies() { - return Collections.unmodifiableMap(brokenDependencies); - } - - void prepareUninstall() { - String compId; - while ((compId = input.nextParameter()) != null) { - if (toUninstall.containsKey(compId)) { - continue; - } - ComponentInfo info = input.getLocalRegistry().loadSingleComponent(compId.toLowerCase(), true); - if (info == null) { - throw feedback.failure("UNINSTALL_UnknownComponentId", null, compId); - } - if (info.getId().equals(BundleConstants.GRAAL_COMPONENT_ID)) { - throw feedback.failure("UNINSTALL_CoreComponent", null, compId); - } - if (info.isNativeComponent()) { - throw feedback.failure("UNINSTALL_NativeComponent", null, info.getId(), info.getName()); - } - if (info.getDistributionType() != DistributionType.OPTIONAL) { - throw feedback.failure("UNINSTALL_BundledComponent", null, info.getId(), info.getName()); - } - toUninstall.put(compId, info); - } - - if (input.hasOption(Commands.OPTION_NO_DEPENDENCIES)) { - return; - } - - for (ComponentInfo u : toUninstall.values()) { - Set br = registry.findDependentComponents(u, true); - if (!br.isEmpty()) { - brokenDependencies.put(u, br); - } - } - } - - void checkBrokenDependencies() { - if (brokenDependencies.isEmpty()) { - return; - } - Set uninstalled = new HashSet<>(toUninstall.values()); - // get all broken components, excluding the ones scheduled for uninstall - Stream stm = brokenDependencies.values().stream().flatMap((col) -> col.stream()).filter((c) -> !uninstalled.contains(c)); - // if all broken are uninstalled -> OK - if (!stm.findFirst().isPresent()) { - return; - } - - List sorted = new ArrayList<>(brokenDependencies.keySet()); - P printer; - boolean warning = removeDependent || breakDependent; - if (warning) { - printer = feedback::output; - feedback.output(removeDependent ? "UNINSTALL_BrokenDependenciesRemove" : "UNINSTALL_BrokenDependenciesWarn"); - } else { - printer = (a, b) -> feedback.error(a, null, b); - feedback.error("UNINSTALL_BrokenDependencies", null); - } - Comparator c = (a, b) -> a.getId().compareToIgnoreCase(b.getId()); - Collections.sort(sorted, c); - for (ComponentInfo i : sorted) { - List deps = new ArrayList<>(brokenDependencies.get(i)); - deps.removeAll(uninstalled); - if (deps.isEmpty()) { - continue; - } - Collections.sort(sorted, c); - - if (!warning) { - printer.print("UNINSTALL_BreakDepSource", i.getName(), i.getId()); - } - for (ComponentInfo d : deps) { - printer.print("UNINSTALL_BreakDepTarget", d.getName(), d.getId()); - } - } - if (warning) { - return; - } - throw feedback.failure("UNINSTALL_BreakDependenciesTerminate", null); - } - - void includeAndOrderComponents() { - Set allBroken = new LinkedHashSet<>(); - if (!(input.hasOption(Commands.OPTION_NO_DEPENDENCIES) || breakDependent)) { - for (Collection ii : brokenDependencies.values()) { - allBroken.addAll(ii); - } - for (ComponentInfo ci : allBroken) { - Set br = registry.findDependentComponents(ci, true); - if (!br.isEmpty()) { - allBroken.addAll(br); - brokenDependencies.put(ci, br); - } - } - - if (removeDependent) { - Set newBroken = new HashSet<>(); - for (ComponentInfo i : allBroken) { - ComponentInfo full = registry.loadSingleComponent(i.getId(), true); - newBroken.add(full); - toUninstall.put(i.getId(), full); - } - allBroken = newBroken; - } - } - - List leaves = new ArrayList<>(toUninstall.values()); - leaves.removeAll(allBroken); - - List ordered = new ArrayList<>(toUninstall.size()); - ordered.addAll(leaves); - - int top = leaves.size(); - for (ComponentInfo ci : allBroken) { - Set check = new HashSet<>(); - CatalogContents.findDependencies(ci, true, Boolean.TRUE, check, (a, b, c, d) -> registry.findComponentMatch(a, b, true)); - int i; - for (i = ordered.size(); i > top; i--) { - ComponentInfo c = ordered.get(i - 1); - if (check.contains(c)) { - break; - } - } - ordered.add(i, ci); - } - Collections.reverse(ordered); - this.uninstallSequence = ordered; - } - - interface P { - void print(String key, Object... params); - } - - @Override - public int execute() throws IOException { - registry.verifyAdministratorAccess(); - if (input.optValue(Commands.OPTION_HELP) != null) { - feedback.output("UNINSTALL_Help"); - return 0; - } - if (!input.hasParameter()) { - feedback.output("UNINSTALL_ParametersMissing"); - return 1; - } - prepareUninstall(); - checkBrokenDependencies(); - includeAndOrderComponents(); - for (ComponentInfo info : uninstallSequence) { - try { - uninstallSingleComponent(info); - } catch (InstallerStopException | IOException ex) { - if (ignoreFailures) { - feedback.error("UNINSTALL_IgnoreFailed", ex, - info.getId(), ex.getLocalizedMessage()); - } else { - feedback.error("UNINSTALL_ErrorDuringProcessing", ex, info.getId()); - throw ex; - } - } - } - return 0; - } - - void uninstallSingleComponent(ComponentInfo info) throws IOException { - Uninstaller inst = new Uninstaller(feedback, input.getFileOperations(), - info, input.getLocalRegistry()); - configureInstaller(inst); - - feedback.output("UNINSTALL_UninstallingComponent", - info.getId(), info.getName(), info.getVersionString()); - doUninstallSingle(inst); - } - - // overriden in tests - void doUninstallSingle(Uninstaller inst) throws IOException { - inst.uninstall(); - } - - private void configureInstaller(Uninstaller inst) { - inst.setInstallPath(input.getGraalHomePath()); - inst.setDryRun(input.optValue(Commands.OPTION_DRY_RUN) != null); - inst.setIgnoreFailedDeletions(input.optValue(Commands.OPTION_IGNORE_FAILURES) != null); - inst.setPreservePaths( - new HashSet<>(registry.getPreservedFiles(inst.getComponentInfo()))); - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Uninstaller.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Uninstaller.java deleted file mode 100644 index 976ae79aa99b..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/Uninstaller.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; - -public class Uninstaller { - private final Feedback feedback; - private final ComponentInfo componentInfo; - private final ComponentRegistry registry; - private final FileOperations fileOps; - - private PreRemoveProcess preRemove; - private Set preservePaths = Collections.emptySet(); - private boolean dryRun; - private boolean ignoreFailedDeletions; - private Path installPath; - - private final Set directoriesToDelete = new HashSet<>(); - - public Uninstaller(Feedback feedback, FileOperations fops, ComponentInfo componentInfo, ComponentRegistry registry) { - this.feedback = feedback; - this.componentInfo = componentInfo; - this.registry = registry; - this.fileOps = fops; - } - - public void uninstall() throws IOException { - uninstallContent(); - if (!isDryRun()) { - registry.removeComponent(componentInfo); - } - } - - void uninstallContent() throws IOException { - preRemove = new PreRemoveProcess(installPath, fileOps, feedback) - .setDryRun(isDryRun()) - .setIgnoreFailedDeletions(isIgnoreFailedDeletions()); - // remove all the files occupied by the component - O: for (String p : componentInfo.getPaths()) { - if (preservePaths.contains(p)) { - feedback.verboseOutput("INSTALL_SkippingSharedFile", p); - continue; - } - // assert relative path - Path toDelete = installPath.resolve(SystemUtils.fromCommonRelative(p)); - if (Files.isDirectory(toDelete)) { - for (String s : preservePaths) { - Path x = SystemUtils.fromCommonRelative(s); - if (x.startsWith(p)) { - // will not delete directory with something shared or system. - continue O; - } - } - directoriesToDelete.add(p); - continue; - } - feedback.verboseOutput("UNINSTALL_DeletingFile", p); - if (!dryRun) { - // ignore missing files, handle permissions - preRemove.deleteOneFile(toDelete); - } - } - List dirNames = new ArrayList<>(directoriesToDelete); - preRemove.processComponent(componentInfo); - Collections.sort(dirNames); - Collections.reverse(dirNames); - for (String s : dirNames) { - Path p = installPath.resolve(SystemUtils.fromCommonRelative(s)); - feedback.verboseOutput("UNINSTALL_DeletingDirectory", p); - if (!dryRun) { - try { - fileOps.deleteFile(p); - } catch (IOException ex) { - if (ignoreFailedDeletions) { - feedback.error("INSTALL_FailedToDeleteDirectory", ex, p, ex.getLocalizedMessage()); - } else { - throw ex; - } - } - } - } - } - - public boolean isIgnoreFailedDeletions() { - return ignoreFailedDeletions; - } - - public void setIgnoreFailedDeletions(boolean ignoreFailedDeletions) { - this.ignoreFailedDeletions = ignoreFailedDeletions; - } - - public boolean isDryRun() { - return dryRun; - } - - public void setDryRun(boolean dryRun) { - this.dryRun = dryRun; - } - - public Path getInstallPath() { - return installPath; - } - - public void setInstallPath(Path installPath) { - this.installPath = installPath; - } - - public Set getPreservePaths() { - return preservePaths; - } - - public void setPreservePaths(Set preservePaths) { - this.preservePaths = preservePaths; - } - - public ComponentInfo getComponentInfo() { - return componentInfo; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeCommand.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeCommand.java deleted file mode 100644 index 97aceff02fa2..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeCommand.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.ComponentInstaller; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerCommand; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * - */ -public class UpgradeCommand implements InstallerCommand { - private static final Map options = new HashMap<>(); - - private final boolean allowDistUpgrades; - private CommandInput input; - private Feedback feedback; - private UpgradeProcess helper; - private boolean verifyJars = true; - - static { - options.put(Commands.OPTION_IGNORE_MISSING_COMPONENTS, ""); - options.put(Commands.LONG_OPTION_IGNORE_MISSING_COMPONENTS, Commands.OPTION_IGNORE_MISSING_COMPONENTS); - options.put(Commands.OPTION_NO_VERIFY_JARS, ""); - - options.put(Commands.OPTION_NO_DOWNLOAD_PROGRESS, ""); - options.put(Commands.LONG_OPTION_NO_DOWNLOAD_PROGRESS, Commands.OPTION_NO_DOWNLOAD_PROGRESS); - options.put(Commands.LONG_OPTION_NO_VERIFY_JARS, Commands.OPTION_NO_VERIFY_JARS); - - options.put(Commands.OPTION_USE_EDITION, "s"); - options.put(Commands.LONG_OPTION_USE_EDITION, Commands.OPTION_USE_EDITION); - - options.put(Commands.OPTION_TARGET_DIRECTORY, "s"); - options.put(Commands.LONG_OPTION_TARGET_DIRECTORY, Commands.OPTION_TARGET_DIRECTORY); - - options.put(Commands.OPTION_NO_SYMLINK, ""); - options.put(Commands.LONG_OPTION_NO_SYMLINK, Commands.OPTION_NO_SYMLINK); - - options.putAll(ComponentInstaller.componentOptions); - } - - public UpgradeCommand(boolean allowDistUpgrades) { - this.allowDistUpgrades = allowDistUpgrades; - } - - public UpgradeCommand() { - this(true); - } - - @Override - public Map supportedOptions() { - return allowDistUpgrades ? options : Collections.emptyMap(); - } - - protected boolean allowDistUpgrades() { - return allowDistUpgrades; - } - - UpgradeProcess getProcess() { - return helper; - } - - protected void initUpgradeOptions() { - ComponentCollection coll = input.getRegistry(); - coll.setAllowDistUpdate(allowDistUpgrades()); - if (input.optValue(Commands.OPTION_IGNORE_MISSING_COMPONENTS) != null) { - helper.setAllowMissing(true); - } - if (input.optValue(Commands.OPTION_NO_VERIFY_JARS) != null) { - verifyJars = false; - } - String ed = input.optValue(Commands.OPTION_USE_EDITION); - if (ed != null) { - helper.setEditionUpgrade(ed); - } - } - - @Override - public void init(CommandInput commandInput, Feedback feedBack) { - this.input = commandInput; - this.feedback = feedBack.withBundle(UpgradeCommand.class); - helper = new UpgradeProcess(input, feedBack, commandInput.getRegistry()); - initUpgradeOptions(); - } - - ComponentInfo configureProcess() throws IOException { - input.existingFiles().setVerifyJars(verifyJars); - Version min = input.getLocalRegistry().getGraalVersion(); - - String s = input.peekParameter(); - Version v = min; - Version.Match filter = min.match(allowDistUpgrades() ? Version.Match.Type.MOSTRECENT : Version.Match.Type.COMPATIBLE); - if (s != null) { - try { - Version.Match.Type mt = Version.Match.Type.COMPATIBLE; - if (s.startsWith("=")) { - mt = Version.Match.Type.EXACT; - s = s.substring(1); - } else if (s.startsWith("+")) { - mt = Version.Match.Type.INSTALLABLE; - s = s.substring(1); - } - v = Version.fromUserString(s); - // cannot just compare user vs. graal, must match the user to the list of Graals to - // resolve the - // uncertaint parts (-x and possible suffix) - filter = v.match(mt); - if (min.compareTo(v) > 0) { - throw feedback.failure("UPGRADE_CannotDowngrade", null, v.displayString()); - } - input.nextParameter(); - input.existingFiles().matchVersion(filter); - } catch (IllegalArgumentException ex) { - // not a version, continue with component upgrade - } - } - // allow dist upgrade when searching for components - for (ComponentParam p : input.existingFiles()) { - helper.addComponent(p); - } - ComponentInfo info = helper.findGraalVersion(filter); - return info; - } - - @Override - public int execute() throws IOException { - input.getLocalRegistry().verifyAdministratorAccess(); - - if (input.optValue(Commands.OPTION_HELP) != null) { - feedback.output(allowDistUpgrades ? "UPGRADE_Help" : "UPDATE_Help"); - return 0; - } - try (UpgradeProcess h = this.helper) { - ComponentInfo info = configureProcess(); - boolean workDone; - - if (allowDistUpgrades) { - workDone = h.installGraalCore(info); - } else { - workDone = false; - } - h.installAddedComponents(); - if (h.addedComponents().isEmpty()) { - return workDone ? 0 : 1; - } - } - return 0; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeProcess.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeProcess.java deleted file mode 100644 index 2cf13d1f6deb..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/commands/UpgradeProcess.java +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.commands; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.ComponentInstaller; -import org.graalvm.component.installer.ComponentIterable; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.UnknownVersionException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.persist.DirectoryStorage; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.remote.CatalogIterable; - -/** - * Drives the GraalVM core upgrade process. - * - * @author sdedic - */ -public class UpgradeProcess implements AutoCloseable { - private final CommandInput input; - private final Feedback feedback; - private final ComponentCollection catalog; - - private final Set existingComponents = new HashSet<>(); - private final Set addComponents = new HashSet<>(); - private final Set migrated = new HashSet<>(); - private final Set explicitIds = new HashSet<>(); - - private ComponentInfo targetInfo; - private Path newInstallPath; - private Path newGraalHomePath; - private MetadataLoader metaLoader; - private boolean allowMissing; - private ComponentRegistry newGraalRegistry; - private Version minVersion = Version.NO_VERSION; - private String editionUpgrade; - private Set acceptedLicenseIDs = new HashSet<>(); - - public UpgradeProcess(CommandInput input, Feedback feedback, ComponentCollection catalog) { - this.input = input; - this.feedback = feedback.withBundle(UpgradeProcess.class); - this.catalog = catalog; - resetExistingComponents(); - } - - final void resetExistingComponents() { - existingComponents.clear(); - existingComponents.addAll(input.getLocalRegistry().getComponentIDs().stream().filter((id) -> { - ComponentInfo info = input.getLocalRegistry().findComponent(id); - // only auto-include the 'leaf' components - return info != null && input.getLocalRegistry().findDependentComponents(info, false).isEmpty(); - }).collect(Collectors.toList())); - existingComponents.remove(BundleConstants.GRAAL_COMPONENT_ID); - } - - public String getEditionUpgrade() { - return editionUpgrade; - } - - public void setEditionUpgrade(String editionUpgrade) { - this.editionUpgrade = editionUpgrade; - } - - /** - * Adds a component to install to the upgraded core. - * - * @param info the component to install. - */ - public void addComponent(ComponentParam info) throws IOException { - addComponents.add(info); - explicitIds.add(info.createMetaLoader().getComponentInfo().getId().toLowerCase(Locale.ENGLISH)); - } - - public Set addedComponents() { - return addComponents; - } - - public boolean isAllowMissing() { - return allowMissing; - } - - public void setAllowMissing(boolean allowMissing) { - this.allowMissing = allowMissing; - } - - Path getNewInstallPath() { - return newInstallPath; - } - - public List allComponents() throws IOException { - Set ids = new HashSet<>(); - ArrayList allComps = new ArrayList<>(addedComponents()); - for (ComponentParam p : allComps) { - ids.add(p.createMetaLoader().getComponentInfo().getId()); - } - for (ComponentInfo mig : migrated) { - if (ids.contains(mig.getId())) { - continue; - } - allComps.add(input.existingFiles().createParam(mig.getId(), mig)); - } - return allComps; - } - - /** - * Access to {@link ComponentRegistry} in the new instance. - * - * @return registry in the new instance. - */ - public ComponentRegistry getNewGraalRegistry() { - return newGraalRegistry; - } - - /** - * Finds parent path for the new GraalVM installation. Note that on MacOs X the "JAVA_HOME" is - * below the installation root, so on MacOS X the installation root is returned. - * - * @return installation root for the core package. - */ - Path findGraalVMParentPath() { - Path vmRoot = input.getGraalHomePath().normalize(); - if (vmRoot.getNameCount() == 0) { - return null; - } - Path skipPath = SystemUtils.getGraalVMJDKRoot(input.getLocalRegistry()); - Path skipped = vmRoot; - while (skipPath != null && skipped != null && skipPath.getNameCount() > 0 && - Objects.equals(skipPath.getFileName(), skipped.getFileName())) { - skipPath = skipPath.getParent(); - skipped = skipped.getParent(); - } - if (skipPath == null || skipPath.getNameCount() == 0) { - vmRoot = skipped; - } - Path parent = vmRoot.getParent(); - // ensure the parent directory is still writable: - if (parent != null && !Files.isWritable(parent)) { - throw feedback.failure("UPGRADE_DirectoryNotWritable", null, parent); - } - return parent; - } - - /** - * Defines name for the install path. The GraalVM core package may define "edition" capability, - * which places "ee" in the name. - * - * @param graal new Graal core component - * @return Path to the installation directory - */ - Path createInstallName(ComponentInfo graal) { - String targetDir = input.optValue(Commands.OPTION_TARGET_DIRECTORY); - Path base; - - if (targetDir != null) { - base = SystemUtils.fromUserString(targetDir); - } else { - base = findGraalVMParentPath(); - } - // "provides" java_version - String jv = graal.getProvidedValue(CommonConstants.CAP_JAVA_VERSION, String.class); - if (jv == null) { - // if not present, then at least "requires" which is autogenerated from release file. - jv = graal.getRequiredGraalValues().get(CommonConstants.CAP_JAVA_VERSION); - } - if (jv == null) { - jv = input.getLocalRegistry().getGraalCapabilities().get(CommonConstants.CAP_JAVA_VERSION); - } - String ed = graal.getProvidedValue(CommonConstants.CAP_EDITION, String.class); - if (ed == null) { - // maybe we do install a specific edition ? - if (editionUpgrade != null) { - ed = editionUpgrade; - } else { - ed = input.getLocalRegistry().getGraalCapabilities().get(CommonConstants.CAP_EDITION); - } - } - String dirName = feedback.l10n( - ed == null ? "UPGRADE_GraalVMDirName@" : "UPGRADE_GraalVMDirNameEdition@", - graal.getVersion().displayString(), - ed, - jv); - return base.resolve(SystemUtils.fileName(dirName)); - } - - /** - * Prepares the installation of the core Component. Returns {@code false} if the upgrade is not - * necessary or not found. - * - * @param info - * @return true, if the graalvm should be updated. - * @throws IOException - */ - boolean prepareInstall(ComponentInfo info) throws IOException { - Version min = input.getLocalRegistry().getGraalVersion(); - if (info == null) { - feedback.message("UPGRADE_NoUpdateFound", min.displayString()); - return false; - } - int cmp = min.compareTo(info.getVersion()); - if ((cmp > 0) || ((editionUpgrade == null) && (cmp == 0))) { - feedback.message("UPGRADE_NoUpdateLatestVersion", min.displayString()); - migrated.clear(); - return false; - } - - Path reported = createInstallName(info); - // there's a slight chance this will be different from the final name ... - feedback.output("UPGRADE_PreparingInstall", info.getVersion().displayString(), reported); - failIfDirectotyExistsNotEmpty(reported); - - ComponentParam coreParam = createGraalComponentParam(info); - // reuse License logic from the installer command: - InstallCommand cmd = new InstallCommand(); - cmd.init(input, feedback); - - // ask the InstallCommand to process/accept the licenses, if there are any. - MetadataLoader ldr = coreParam.createMetaLoader(); - cmd.addLicenseToAccept(ldr); - cmd.acceptLicenses(); - acceptedLicenseIDs = cmd.getProcessedLicenses(); - - // force download - ComponentParam param = input.existingFiles().createParam("core", info); - metaLoader = param.createFileLoader(); - ComponentInfo completeInfo = metaLoader.completeMetadata(); - newInstallPath = createInstallName(completeInfo); - newGraalHomePath = newInstallPath; - failIfDirectotyExistsNotEmpty(newInstallPath); - - if (!reported.equals(newInstallPath)) { - feedback.error("UPGRADE_WarningEditionDifferent", null, info.getVersion().displayString(), newInstallPath); - } - - existingComponents.addAll(input.getLocalRegistry().getComponentIDs()); - existingComponents.remove(BundleConstants.GRAAL_COMPONENT_ID); - return true; - } - - void failIfDirectotyExistsNotEmpty(Path target) throws IOException { - if (!Files.exists(target)) { - return; - } - if (!Files.isDirectory(target)) { - throw feedback.failure("UPGRADE_TargetExistsNotDirectory", null, target); - } - Path ghome = target.resolve(SystemUtils.getGraalVMJDKRoot(input.getLocalRegistry())); - Path relFile = ghome.resolve("release"); - if (Files.isReadable(relFile)) { - Version targetVersion = null; - try { - ComponentRegistry reg = createRegistryFor(ghome); - targetVersion = reg.getGraalVersion(); - } catch (FailedOperationException ex) { - // ignore - } - if (targetVersion != null) { - throw feedback.failure("UPGRADE_TargetExistsContainsGraalVM", null, target, targetVersion.displayString()); - } - } - if (Files.list(target).findFirst().isPresent()) { - throw feedback.failure("UPGRADE_TargetExistsNotEmpty", null, target); - } - } - - /** - * Completes the component info, loads symlinks, permissions. Same as - * {@link InstallCommand#createInstaller}. - */ - GraalVMInstaller createGraalVMInstaller(ComponentInfo info) throws IOException { - ComponentParam p = createGraalComponentParam(info); - MetadataLoader ldr = p.createFileLoader(); - ldr.loadPaths(); - if (p.isComplete()) { - Archive a; - a = ldr.getArchive(); - a.verifyIntegrity(input); - } - ComponentInfo completeInfo = ldr.getComponentInfo(); - targetInfo = completeInfo; - metaLoader = ldr; - GraalVMInstaller gvmInstaller = new GraalVMInstaller(feedback, - input.getFileOperations(), - input.getLocalRegistry(), completeInfo, catalog, - metaLoader.getArchive()); - // do not create symlinks if disabled, or target directory is given. - boolean disableSymlink = input.hasOption(Commands.OPTION_NO_SYMLINK) || - input.hasOption(Commands.OPTION_TARGET_DIRECTORY); - gvmInstaller.setDisableSymlinks(disableSymlink); - // will make registrations for bundled components, too. - gvmInstaller.setAllowFilesInComponentDir(true); - gvmInstaller.setCurrentInstallPath(input.getGraalHomePath()); - gvmInstaller.setInstallPath(newInstallPath); - gvmInstaller.setPermissions(ldr.loadPermissions()); - gvmInstaller.setSymlinks(ldr.loadSymlinks()); - newGraalHomePath = gvmInstaller.getInstalledPath(); - return gvmInstaller; - } - - /** - * Cached parameter for the core. It will cache MetaLoader and FileLoader for subsequent - * operations. - */ - private ComponentParam graalCoreParam; - private GraalVMInstaller coreInstaller; - - ComponentParam createGraalComponentParam(ComponentInfo info) { - if (graalCoreParam == null) { - graalCoreParam = input.existingFiles().createParam(info.getId(), info); - } - return graalCoreParam; - } - - public boolean installGraalCore(ComponentInfo info) throws IOException { - if (!prepareInstall(info)) { - return false; - } - - GraalVMInstaller gvmInstaller = createGraalVMInstaller(info); - - feedback.output("UPGRADE_InstallingCore", info.getVersion().displayString(), newInstallPath.toString()); - - gvmInstaller.install(); - // allow symlink to be created in close(); the symlink won't obscure paths - // that might contain the symlink during installation of components. - coreInstaller = gvmInstaller; - - Path installed = gvmInstaller.getInstalledPath(); - newGraalRegistry = createRegistryFor(installed); - migrateLicenses(); - return true; - } - - private ComponentRegistry createRegistryFor(Path home) { - DirectoryStorage dst = new DirectoryStorage( - feedback.withBundle(ComponentInstaller.class), - home.resolve(SystemUtils.fromCommonRelative(CommonConstants.PATH_COMPONENT_STORAGE)), - home); - dst.setJavaVersion(input.getLocalRegistry().getJavaVersion()); - return new ComponentRegistry(feedback, dst); - } - - /** - * Checks if the candidate GraalVM satisfies all dependencies of added components. Added - * components are those specified on the commandline; - * - * @param candidate candidate GraalVM component - * @return broken components - */ - Collection satisfiedAddedComponents(ComponentInfo candidate) throws IOException { - List broken = new ArrayList<>(); - Version gv = candidate.getVersion(); - Version.Match satisfies = gv.match(Version.Match.Type.COMPATIBLE); - for (ComponentParam param : addComponents) { - ComponentInfo in = param.createMetaLoader().getComponentInfo(); - String vs = in.getRequiredGraalValues().get(BundleConstants.GRAAL_VERSION); - Version cv = Version.fromString(vs); - if (!satisfies.test(cv)) { - broken.add(in); - if (minVersion.compareTo(cv) < 0) { - minVersion = cv; - } - } - } - return broken; - } - - Set findInstallables(ComponentInfo graal) { - Version gv = graal.getVersion(); - Version.Match satisfies = gv.match(Version.Match.Type.COMPATIBLE); - Set ret = new HashSet<>(); - for (String id : existingComponents) { - if (explicitIds.contains(id)) { - continue; - } - Collection cis = catalog.loadComponents(id, satisfies, false); - if (cis == null || cis.isEmpty()) { - continue; - } - List versions = new ArrayList<>(cis); - ret.add(versions.get(versions.size() - 1)); - } - return ret; - } - - public ComponentInfo getTargetInfo() { - return targetInfo; - } - - private String lowerCaseId(String s) { - return s.toLowerCase(Locale.ENGLISH); - } - - public ComponentInfo findGraalVersion(Version.Match minimum) throws IOException { - Version.Match filter; - if (minimum.getType() == Version.Match.Type.MOSTRECENT) { - filter = minimum.getVersion().match(Version.Match.Type.INSTALLABLE); - } else { - filter = minimum; - } - Collection graals; - try { - graals = catalog.loadComponents(BundleConstants.GRAAL_COMPONENT_ID, - filter, false); - if (graals == null || graals.isEmpty()) { - return null; - } - } catch (UnknownVersionException ex) { - // could not find anything to match the user version against - if (ex.getCandidate() == null) { - throw feedback.failure("UPGRADE_NoSpecificVersion", ex, filter.getVersion().displayString()); - } else { - throw feedback.failure("UPGRADE_NoSpecificVersion2", ex, filter.getVersion().displayString(), ex.getCandidate().displayString()); - } - } - List versions = new ArrayList<>(graals); - Collections.sort(versions, ComponentInfo.versionComparator().reversed()); - for (Iterator it = versions.iterator(); it.hasNext();) { - ComponentInfo candidate = it.next(); - Collection broken = satisfiedAddedComponents(candidate); - if (!broken.isEmpty()) { - it.remove(); - } - } - if (versions.isEmpty()) { - throw feedback.failure("UPGRADE_NoVersionSatisfiesComponents", null, minVersion.toString()); - } - - Set installables = null; - Set first = null; - ComponentInfo result = null; - Set toMigrate = existingComponents.stream().filter((id) -> { - ComponentInfo ci = input.getLocalRegistry().loadSingleComponent(id, false); - return ci.getDistributionType() != DistributionType.BUNDLED; - }).map(this::lowerCaseId).collect(Collectors.toSet()); - toMigrate.removeAll(explicitIds); - - Map> missingParts = new HashMap<>(); - for (Iterator it = versions.iterator(); it.hasNext();) { - ComponentInfo candidate = it.next(); - Set instCandidates = findInstallables(candidate); - if (first == null) { - first = instCandidates; - } - Set canMigrate = instCandidates.stream().map(ComponentInfo::getId).map(this::lowerCaseId).collect(Collectors.toSet()); - if (allowMissing || canMigrate.containsAll(toMigrate)) { - installables = instCandidates; - result = candidate; - break; - } else { - Set miss = new HashSet<>(toMigrate); - miss.removeAll(canMigrate); - missingParts.put(candidate, miss.stream().map((id) -> input.getLocalRegistry().findComponent(id)).collect(Collectors.toSet())); - } - } - if (installables == null) { - if (!allowMissing) { - List reportVersions = new ArrayList<>(missingParts.keySet()); - for (ComponentInfo core : reportVersions) { - List list = new ArrayList<>(missingParts.get(core)); - Collections.sort(list, (a, b) -> a.getId().compareToIgnoreCase(b.getId())); - - String msg = null; - for (ComponentInfo ci : list) { - String shortId = input.getLocalRegistry().shortenComponentId(ci); - String s = feedback.l10n("UPGRADE_MissingComponentItem", shortId, ci.getName()); - if (msg == null) { - msg = s; - } else { - msg = feedback.l10n("UPGRADE_MissingComponentListPart", msg, s); - } - } - - feedback.error("UPGRADE_MissingComponents", null, core.getName(), core.getVersion().displayString(), msg); - } - if (editionUpgrade != null) { - throw feedback.failure("UPGRADE_ComponentsMissingFromEdition", null, editionUpgrade); - } else { - throw feedback.failure("UPGRADE_ComponentsCannotMigrate", null); - } - } - if (versions.isEmpty()) { - throw feedback.failure("UPGRADE_NoVersionSatisfiesComponents", null); - } - result = versions.get(0); - installables = first; - } - migrated.clear(); - // if the result GraalVM is identical to current, do not migrate anything. - if (result != null && (!input.getLocalRegistry().getGraalVersion().equals(result.getVersion()) || - input.hasOption(Commands.OPTION_USE_EDITION))) { - migrated.addAll(installables); - targetInfo = result; - } - return result; - } - - public boolean didUpgrade() { - return newGraalRegistry != null; - } - - /* - * public void identifyMigratedCompoents(ComponentInfo target) { if - * (!satisfiedAddedComponents(target)) { throw - * feedback.failure("UPGRADE_NoVersionSatisfiesComponents", null); } this.targetInfo = target; - * this.addComponents.addAll(findInstallables(target)); } - */ - - public void migrateLicenses() { - if (!SystemUtils.isLicenseTrackingEnabled()) { - return; - } - feedback.output("UPGRADE_MigratingLicenses", input.getLocalRegistry().getGraalVersion().displayString(), - targetInfo.getVersion().displayString()); - for (Map.Entry> e : input.getLocalRegistry().getAcceptedLicenses().entrySet()) { - String licId = e.getKey(); - - for (String compId : e.getValue()) { - try { - String t = input.getLocalRegistry().licenseText(licId); - ComponentInfo info = input.getLocalRegistry().findComponent(compId); - Date d = input.getLocalRegistry().isLicenseAccepted(info, licId); - newGraalRegistry.acceptLicense(info, licId, t, d); - } catch (FailedOperationException ex) { - feedback.error("UPGRADE_CannotMigrateLicense", ex, compId, licId); - } - } - } - // dirty way how to migrate GDS settings: - Path gdsSettings = SystemUtils.resolveRelative( - input.getGraalHomePath(), - CommonConstants.PATH_COMPONENT_STORAGE + "/gds"); - if (Files.isDirectory(gdsSettings)) { - Path targetGdsSettings = SystemUtils.resolveRelative( - newInstallPath.resolve(SystemUtils.getGraalVMJDKRoot(newGraalRegistry)), - CommonConstants.PATH_COMPONENT_STORAGE + "/gds"); - try { - SystemUtils.copySubtree(gdsSettings, targetGdsSettings); - } catch (IOException ex) { - feedback.error("UPGRADE_CannotMigrateGDS", ex, ex.getLocalizedMessage()); - } - } - } - - protected InstallCommand configureInstallCommand(InstallCommand instCommand) throws IOException { - List params = new ArrayList<>(); - // add migrated components - params.addAll(allComponents()); - if (params.isEmpty()) { - return null; - } - instCommand.init(new InputDelegate(params), feedback); - instCommand.setAllowUpgrades(true); - instCommand.setForce(true); - instCommand.markLicensesProcessed(acceptedLicenseIDs); - return instCommand; - } - - public void installAddedComponents() throws IOException { - // install all the components - InstallCommand ic = configureInstallCommand(new InstallCommand()); - if (ic != null) { - ic.execute(); - } - } - - @Override - public void close() throws IOException { - if (coreInstaller != null) { - coreInstaller.createSymlink(); - } - for (ComponentParam p : allComponents()) { - p.close(); - } - if (metaLoader != null) { - metaLoader.close(); - } - } - - /** - * The class provides a new local registry in the new installation, and a new component - * registry, for the target graalvm version. - */ - class InputDelegate implements CommandInput { - private final List params; - private int index; - private ComponentCatalog remoteRegistry; - - InputDelegate(List params) { - this.params = params; - } - - @Override - public FileOperations getFileOperations() { - return input.getFileOperations(); - } - - @Override - public CatalogFactory getCatalogFactory() { - return input.getCatalogFactory(); - } - - @Override - public ComponentIterable existingFiles() throws FailedOperationException { - return new ComponentIterable() { - @Override - public void setVerifyJars(boolean verify) { - input.existingFiles().setVerifyJars(verify); - } - - @Override - public ComponentParam createParam(String cmdString, ComponentInfo info) { - return new CatalogIterable.CatalogItemParam( - getRegistry().getDownloadInterceptor(), - info, - info.getName(), - cmdString, - feedback, - input.optValue(Commands.OPTION_NO_DOWNLOAD_PROGRESS) == null); - } - - @Override - public Iterator iterator() { - return new Iterator<>() { - boolean init; - - @Override - public boolean hasNext() { - if (!init) { - init = true; - index = 0; - } - return index < params.size(); - } - - @Override - public ComponentParam next() { - if (index >= params.size()) { - throw new NoSuchElementException(); - } - return params.get(index++); - } - - }; - } - - @Override - public ComponentIterable matchVersion(Version.Match m) { - return this; - } - - @Override - public ComponentIterable allowIncompatible() { - return this; - } - }; - } - - @Override - public String requiredParameter() throws FailedOperationException { - if (index >= params.size()) { - throw feedback.failure("UPGRADE_MissingParameter", null); - } - return nextParameter(); - } - - @Override - public String nextParameter() { - if (!hasParameter()) { - return null; - } - return params.get(index++).getSpecification(); - } - - @Override - public String peekParameter() { - if (!hasParameter()) { - return null; - } - return params.get(index).getSpecification(); - } - - @Override - public boolean hasParameter() { - return params.size() > index; - } - - @Override - public Path getGraalHomePath() { - return didUpgrade() ? newGraalHomePath : input.getGraalHomePath(); - } - - @Override - public ComponentCatalog getRegistry() { - if (remoteRegistry == null) { - remoteRegistry = input.getCatalogFactory().createComponentCatalog(this); - } - return remoteRegistry; - } - - @Override - public ComponentRegistry getLocalRegistry() { - if (newGraalRegistry != null) { - return newGraalRegistry; - } else { - return input.getLocalRegistry(); - } - } - - @Override - public String optValue(String option) { - return input.optValue(option); - } - - @Override - public String getParameter(String key, boolean cmdLine) { - return input.getParameter(key, cmdLine); - } - - @Override - public Map parameters(boolean cmdLine) { - return input.parameters(cmdLine); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/Bundle.properties deleted file mode 100644 index 27bd092d18a0..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/Bundle.properties +++ /dev/null @@ -1,10 +0,0 @@ -OLDS_IncompatibleRelease=Unsupported GraalVM release: OS: {0}, arch: {1}, Java version: {2} - -# {0} - the storage file. -# {1} - the error message. -ERR_CouldNotLoadGDS=Could not load GDS settings from {0}: {1}. - -# {0} - the entered e-mail address. -ERR_EmailNotValid=Invalid email address: {0} -# {1} - the error message. -WARN_CannotSaveEmailAddress=Could not save email address: {0} \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GdsCommands.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GdsCommands.java deleted file mode 100644 index afb5bdff43d4..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GdsCommands.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds; - -/** - * - * @author sdedic - */ -public final class GdsCommands { - public static final String OPTION_EMAIL_ADDRESS = "^"; - public static final String LONG_OPTION_EMAIL_ADDRESS = "email"; - public static final String OPTION_GDS_CONFIG = ";"; - public static final String LONG_OPTION_GDS_CONFIG = "config"; - public static final String OPTION_SHOW_TOKEN = "}"; - public static final String LONG_OPTION_SHOW_TOKEN = "show-ee-token"; - - public static final String OPTION_REVOKE_TOKEN = "{"; - public static final String LONG_OPTION_REVOKE_TOKEN = "revoke-token"; - public static final String OPTION_REVOKE_CURRENT_TOKEN = "~"; - public static final String LONG_OPTION_REVOKE_CURRENT_TOKEN = "revoke-current-token"; - public static final String OPTION_REVOKE_ALL_TOKENS = "1"; - public static final String LONG_OPTION_REVOKE_ALL_TOKENS = "revoke-all-tokens"; -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GraalChannelBase.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GraalChannelBase.java deleted file mode 100644 index c36699ab0e1f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/GraalChannelBase.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds; - -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.remote.FileDownloader; -import java.io.IOException; -import java.net.URL; -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -/** - * Abstracted common base for GDSChannel and GraalChannel. - * - * @author odouda - */ -public abstract class GraalChannelBase implements SoftwareChannel, ComponentCatalog.DownloadInterceptor { - protected final ComponentRegistry localRegistry; - protected final CommandInput input; - protected final Feedback fb; - - /** - * URL of the relases resource. Used for relative URL resolution. - */ - private URL indexURL; - - /** - * Delay-init storage. Make lazy, as the storage calls back to the toplevel registry. Prevents - * stack overflow. - */ - private final Delayed delayedStorage = new Delayed(); - - /** - * Cached initialized storage. - */ - protected ComponentStorage storage; - - protected String edition; - - /** - * If true, future versions are accepted as well. - */ - private boolean allowUpdates = false; - - public GraalChannelBase(CommandInput aInput, Feedback aFeedback, ComponentRegistry aRegistry) { - if (aInput == null) { - throw new IllegalArgumentException("CommandInput cannot be null."); - } - this.input = aInput; - if (aFeedback == null) { - throw new IllegalArgumentException("Feedback cannot be null."); - } - this.fb = aFeedback; - if (aRegistry == null) { - throw new IllegalArgumentException("ComponentRegistry cannot be null."); - } - this.localRegistry = aRegistry; - } - - public String getEdition() { - return edition; - } - - public void setEdition(String edition) { - this.edition = edition; - } - - public boolean isAllowUpdates() { - return allowUpdates; - } - - public void setAllowUpdates(boolean allowUpdates) { - this.allowUpdates = allowUpdates; - } - - public URL getIndexURL() { - return indexURL; - } - - public final void setIndexURL(URL releasesIndexURL) { - this.indexURL = releasesIndexURL; - } - - @Override - public ComponentStorage getStorage() throws IOException { - return delayedStorage; - } - - /** - * Delay-init storage. As listing (downloading) the catalogs require access to the toplevel - * registry, the toplevel needs to finish the initialization first. - */ - class Delayed implements ComponentStorage { - private ComponentStorage init() throws IOException { - if (storage == null) { - allowUpdates = input.getRegistry().isAllowDistUpdate(); - storage = loadStorage(); - } - return storage; - } - - @Override - public Set listComponentIDs() throws IOException { - return init().listComponentIDs(); - } - - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - return init().loadComponentFiles(ci); - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - return init().loadComponentMetadata(id); - } - - @Override - public Map loadGraalVersionInfo() { - return Collections.emptyMap(); - } - } - - static final class NullStorage implements ComponentStorage { - @Override - public Set listComponentIDs() throws IOException { - return Collections.emptySet(); - } - - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - return null; - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - return Collections.emptySet(); - } - - @Override - public Map loadGraalVersionInfo() { - return Collections.emptyMap(); - } - } - - /** - * On first invocation, throws an exception (will be caught by catalog builder). On subsequent - * invocations, returns a dummy no-component storage. - * - * @return empty storage - */ - protected ComponentStorage throwEmptyStorage() { - if (storage != null) { - return storage; - } - Map caps = localRegistry.getGraalCapabilities(); - String os = caps.get(CommonConstants.CAP_OS_NAME); - String arch = caps.get(CommonConstants.CAP_OS_ARCH); - storage = new NullStorage(); - throw new IncompatibleException(fb.l10n("OLDS_IncompatibleRelease", - SystemUtils.normalizeOSName(os, arch), - SystemUtils.normalizeArchitecture(os, arch), - localRegistry.getJavaVersion())); - } - - /** - * Filters mismatched releases. At this point, accepts only the exactly same release version. - * Could be changed to accept future versions as well, allowing for upgrades. - * - * @param graalVersion current version - * @param vers the version from the release entry - * @return true, if the release matches the current installation - */ - protected boolean acceptsVersion(Version graalVersion, Version vers) { - int c = graalVersion.installVersion().compareTo(vers.installVersion()); - return isAllowUpdates() ? c <= 0 : c == 0; - } - - /** - * Initializes the component storage. Loads the releases index, selects matching releases and - * creates {@link org.graalvm.component.installer.ce.WebCatalog} for each of the catalogs. - * Merges using {@link org.graalvm.component.installer.remote.MergeStorage}. - * - * @return merged storage. - * @throws IOException in case of an I/O error. - */ - protected abstract ComponentStorage loadStorage() throws IOException; - - @Override - public FileDownloader processDownloader(ComponentInfo info, FileDownloader dn) { - return configureDownloader(info, dn); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/MailStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/MailStorage.java deleted file mode 100644 index 8e3d01122d76..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/MailStorage.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Properties; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentRegistry; -import java.util.regex.Pattern; - -/** - * - * @author sdedic - */ -public class MailStorage { - static final Path PROPERTIES_PATH = SystemUtils.fromCommonRelative(CommonConstants.PATH_COMPONENT_STORAGE + - "/gds/gds.properties"); - static final String PROP_LAST_EMAIL = "last.email"; // NOI18N - - private final ComponentRegistry localRegistry; - private final Feedback feedback; - - private Properties properties; - private Path propertiesPath; - private Path storagePath; - private boolean changed; - - public MailStorage(ComponentRegistry localRegistry, Feedback feedback) { - this.localRegistry = localRegistry; - this.feedback = feedback; - } - - public void setStorage(Path storage) { - this.storagePath = storage; - propertiesPath = storagePath.resolve(PROPERTIES_PATH); - } - - private Properties load() { - localRegistry.getManagementStorage(); - if (properties != null) { - return properties; - } - if (!Files.exists(propertiesPath)) { - properties = new Properties(); - } else { - try (InputStream is = Files.newInputStream(propertiesPath)) { - Properties read = new Properties(); - read.load(is); - this.properties = read; - } catch (IOException ex) { - feedback.error("ERR_CouldNotLoadGDS", ex, propertiesPath, ex.getLocalizedMessage()); - properties = new Properties(); - } - } - return properties; - } - - public String getEmailAddress() { - load(); - return properties.getProperty(PROP_LAST_EMAIL); - } - - public void setEmailAddress(String mailAddress) { - Properties props = load(); - - if (mailAddress == null) { - if (props.containsKey(PROP_LAST_EMAIL)) { - props.remove(PROP_LAST_EMAIL); - changed = true; - } else { - return; - } - } else { - String p = getEmailAddress(); - if (mailAddress.equals(p)) { - return; - } - props.setProperty(PROP_LAST_EMAIL, mailAddress); - } - changed = true; - } - - public void save() throws IOException { - if (!changed || properties == null || propertiesPath == null) { - return; - } - Path parent = propertiesPath.getParent(); - if (parent == null) { - // cannot happen, but Spotbugs keeps yelling - return; - } - Files.createDirectories(propertiesPath.getParent()); - try (OutputStream os = Files.newOutputStream(propertiesPath)) { - properties.store(os, null); - } - } - - /** - * Simple regexp pattern for verifying an e-mail. Definition taken from - * https://www.w3.org/TR/html52/sec-forms.html#valid-e-mail-address; does not support - * internationalized domains well. - */ - private static final Pattern EMAIL_PATTERN = Pattern - .compile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"); - - public static String checkEmailAddress(String mail, Feedback fb) { - String m; - if (mail == null) { - return null; - } else { - m = mail.trim(); - } - if ("".equals(m)) { - return null; - } - if (!EMAIL_PATTERN.matcher(m).matches()) { - throw fb.failure("ERR_EmailNotValid", null, m); - } - return mail; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/ArtifactParser.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/ArtifactParser.java deleted file mode 100644 index 4bf939e8d68e..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/ArtifactParser.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.SystemUtils.OS; -import org.graalvm.component.installer.SystemUtils.ARCH; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.StabilityLevel; -import org.graalvm.component.installer.persist.HeaderParser; -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONObject; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - -/** - * - * @author odouda - */ -class ArtifactParser { - private static final String JSON_META = "metadata"; - private static final String JSON_META_KEY = "key"; - private static final String JSON_META_VAL = "value"; - private static final String JSON_ID = "id"; - private static final String JSON_NAME = "displayName"; - private static final String JSON_LICENSE = "licenseId"; - private static final String JSON_LICENSE_LABEL = "licenseName"; - private static final String JSON_LICENSE_IMPLICITLY_ACCEPTED = "isLicenseImplicitlyAccepted"; - private static final String JSON_HASH = "checksum"; - - private static final String META_VERSION = "version"; - private static final String META_EDITION = "edition"; - private static final String META_JAVA = "java"; - private static final String META_ARCH = "arch"; - private static final String META_OS = "os"; - private static final String META_STABILITY_LEVEL = "stabilityLevel"; - private static final String META_STABILITY = "stability"; - private static final String META_SYMBOLIC_NAME = "symbolicName"; - private static final String META_DEPENDENCY = "requireBundle"; - private static final String META_REQUIRED = "requiredCapabilities"; - private static final String META_PROVIDED = "providedCapabilities"; - private static final String META_WORK_DIR = "workingDirectories"; - - private final JSONObject json; - - ArtifactParser(JSONObject json) { - if (json == null) { - throw new IllegalArgumentException("Parsed Artifact JSON cannot be null."); - } - this.json = json; - checkContent(); - } - - private void checkContent() { - getId(); - getChecksum(); - getMetadata(); - abreviatedDisplayName(); - getLicenseId(); - getLicenseName(); - } - - public String getVersion() { - return getMetadata(META_VERSION); - } - - public String getJava() { - String java = getMetadata(META_JAVA, () -> Integer.toString(SystemUtils.getJavaMajorVersion())); - if (java.startsWith("jdk")) { - java = java.substring(3); - } - return java; - } - - public String getArch() { - return getMetadata(META_ARCH, () -> ARCH.get().getName()); - } - - public String getOs() { - return getMetadata(META_OS, () -> OS.get().getName()); - } - - public String getEdition() { - return getMetadata(META_EDITION); - } - - private JSONArray getMetadata() { - return json.getJSONArray(JSON_META); - } - - private String getId() { - return json.getString(JSON_ID); - } - - public String getLabel() { - return getMetadata(META_SYMBOLIC_NAME); - } - - private String getDisplayName() { - return json.getString(JSON_NAME); - } - - private String getLicenseId() { - return json.getString(JSON_LICENSE); - } - - private String getChecksum() { - return json.getString(JSON_HASH); - } - - private String getLicenseName() { - return json.getString(JSON_LICENSE_LABEL); - } - - private boolean getIsImplicitlyAccepted() { - boolean out = false; - if (json.has(JSON_LICENSE_IMPLICITLY_ACCEPTED)) { - out = json.getBoolean(JSON_LICENSE_IMPLICITLY_ACCEPTED); - } - return out; - } - - private String getStability() { - return getMetadata(META_STABILITY_LEVEL, () -> getMetadata(META_STABILITY)); - } - - private String getRequiredDependency() { - return getMetadata(META_DEPENDENCY); - } - - private String getRequiredCapabilities() { - return getMetadata(META_REQUIRED); - } - - private String getProvidedCapabilities() { - return getMetadata(META_PROVIDED); - } - - private String getWorkingDir() { - return getMetadata(META_WORK_DIR); - } - - public ComponentInfo asComponentInfo(GDSRESTConnector connector, Feedback fb) { - return fillInComponent( - new ComponentInfo( - getLabel(), - abreviatedDisplayName(), - getVersion(), - getChecksum()), - connector, - fb); - } - - private ComponentInfo fillInComponent(ComponentInfo info, GDSRESTConnector connector, Feedback fb) { - info.addRequiredValues(translateRequiredValues(fb)); - info.addProvidedValues(translateProvidedValues(fb)); - info.setDependencies(translateDependency(fb)); - info.setStability(translateStability()); - info.addWorkingDirectories(translateWorkingDirs()); - info.setLicenseType(getLicenseName()); - info.setLicensePath(connector.makeLicenseURL(getLicenseId())); - info.setOrigin(connector.makeArtifactsURL(getJava())); - info.setRemoteURL(connector.makeArtifactDownloadURL(getId())); - info.setShaDigest(SystemUtils.toHashBytes(getChecksum())); - info.setImplicitlyAccepted(getIsImplicitlyAccepted()); - return info; - } - - private Map translateRequiredValues(Feedback fb) { - String req = getRequiredCapabilities(); - if (req == null) { - return Collections.emptyMap(); - } - return new HeaderParser("GDS Required capabilities.", req, fb).parseRequiredCapabilities(); - } - - private String abreviatedDisplayName() { - String dispName = getDisplayName(); - String osName = getOs(); - if (OS.fromName(osName) == OS.MAC) { - osName = dispName.contains(CommonConstants.OS_TOKEN_MAC) - ? CommonConstants.OS_TOKEN_MAC - : CommonConstants.OS_MACOS_DARWIN; - } - return dispName.substring(0, dispName.indexOf(osName)).trim(); - } - - private Map translateProvidedValues(Feedback fb) { - String prov = getProvidedCapabilities(); - if (prov == null || prov.isBlank()) { - return Collections.emptyMap(); - } - return new HeaderParser("GDS Provided capabilities.", prov, fb).parseProvidedCapabilities(); - } - - private Collection translateWorkingDirs() { - String dir = getWorkingDir(); - if (dir == null || dir.isBlank()) { - return Collections.emptyList(); - } - return Collections.singleton(dir); - } - - private StabilityLevel translateStability() { - return StabilityLevel.fromName(getStability()); - } - - private Set translateDependency(Feedback fb) { - String dep = getRequiredDependency(); - if (dep == null || dep.isBlank()) { - return Collections.emptySet(); - } - return new HeaderParser("GDS Dependencies.", dep, fb).parseDependencies(); - } - - private String getMetadata(String key) { - return getMetadata(key, () -> null); - } - - private String getMetadata(String key, Supplier defValue) { - for (Object o : getMetadata()) { - JSONObject mo = (JSONObject) o; - if (key.equals(mo.getString(JSON_META_KEY))) { - return mo.getString(JSON_META_VAL); - } - } - return defValue.get(); - } - - @Override - public String toString() { - return json.toString(); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/Bundle.properties deleted file mode 100644 index 4314404e4ddd..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/Bundle.properties +++ /dev/null @@ -1,66 +0,0 @@ -OLDS_InvalidReleasesFile=Invalid releases file. -OLDS_ReleaseFile=Artifacts catalog -OLDS_IncompatibleRelease=Unsupported GraalVM release: OS: {0}, arch: {1}, java version: {2} -OLDS_ErrorReadingRelease=Error reading release {0}: {1} - -# {0} - malformed url string -ERR_MalformedArtifactUrl=Malformed artifact download URL: {0} - -# {0} - the storage file -# {1} - the error message -<<<<<<< HEAD -ERR_CouldNotLoadToken=Could not retrieve a download token from {0}: {1}. -ERR_CouldNotRemoveToken=Could not remove a download token from your configuration. -======= -ERR_CouldNotLoadToken=Could not retrieve download token from {0}: {1}. -ERR_CouldNotRemoveToken=Could not remove download token from your configuration. ->>>>>>> d72d4507f72 ([GR-43446] Revoke GDS token feature.) -# {0} - the URL -# {1} - the error message -ERR_CouldNotLoadGDS=Could not retrieve information from {0}: {1}. -ERR_EmailAddressMissing=An email address is required to download from the Oracle Graal download service. -# {0} - user's email address -ERR_VerificationEmail=Failed to send verification email to {0}. -# {0} - response body -ERR_ResponseBody=Failed to parse response body. Response: {0} -# {0} - user's download token -ERR_InvalidToken=The download token "{0}" has not been validated. Please check your email and then press ENTER to continue. -# {0} - user's download token -ERR_WrongToken=The download token "{0}" is not valid. - -MSG_EmailAddressEntry=Please provide an email address. \ - Please review Oracle's Privacy Policy (https://www.oracle.com/legal/privacy/privacy-policy.html). -PROMPT_EmailAddressEntry=Enter a valid email address: -# {0} - user's email address -PROMPT_VerifyEmailAddressEntry=The license has been sent to {0}. Accept it and then press ENTER to continue. -MSG_YourEmail=your email -MSG_InputTokenEntry=Enter your download token and press ENTER, or press ENTER to generate a new download token. -PROMPT_InputTokenEntry=Enter a valid download token: -# {0} - download token -MSG_ObtainedToken=Obtained download token "{0}". -# {0} - the entered email address. -ERR_EmailNotValid=Invalid email address: {0} -# {0} - GDS config savefile -WARN_CannotSaveToken=Could not save download token to file: {0} -# {0} - download token -# {1} - download token source -MSG_PrintToken={0}\ntaken from {1}. -# {0} - file path -MSG_PrintTokenFile=default configuration file "{0}" -# {0} - file path -MSG_PrintTokenCmdFile=user-defined configuration file "{0}" -# {0} - env property name -MSG_PrintTokenEnv=Environment property "{0}" -MSG_EmptyToken=There is no saved download token. - -MSG_AcceptRevoke=Please check your email for a message asking you to confirm that you want to revoke your download token(s). -MSG_NoGDSAddress=There is no GDS address to connect to in your GraalVM installation. -MSG_NoRevokableToken=There is no GDS download token to revoke in your configuration. -MSG_NoEmail=Email cannot be empty. - -GDS_REST_ExtraOptionsHelp=\ - \t--config path to configuration file\n\ - \t--show-ee-token print current download token\n\ - \t--revoke-current-token revoke current download token\n\ - \t--revoke-token revoke specified download token\n\ - \t--revoke-all-tokens revoke all download tokens for email diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorage.java deleted file mode 100644 index e75d409ac214..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSCatalogStorage.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.persist.AbstractCatalogStorage; -import java.io.IOException; -import java.net.URL; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * - * @author odouda - */ -class GDSCatalogStorage extends AbstractCatalogStorage { - private final Map> components; - - GDSCatalogStorage(ComponentRegistry localRegistry, Feedback feedback, URL baseURL, Collection artifacts) { - super(localRegistry, feedback, baseURL); - components = buildComponentsMap(artifacts); - } - - @Override - public Set listComponentIDs() throws IOException { - return components.keySet(); - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - return components.get(id); - } - - private static Map> buildComponentsMap(Collection artifacts) { - Map> comps = new HashMap<>(); - for (ComponentInfo info : artifacts) { - comps.computeIfAbsent(info.getId(), i -> new HashSet<>()).add(info); - } - return comps; - } - - Map> getComponents() { - return components; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannel.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannel.java deleted file mode 100644 index fd32fbedf831..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannel.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommonConstants; -import static org.graalvm.component.installer.CommonConstants.RELEASE_GDS_PRODUCT_ID_KEY; -import org.graalvm.component.installer.ComponentInstaller; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.gds.GdsCommands; -import org.graalvm.component.installer.gds.GraalChannelBase; -import org.graalvm.component.installer.gds.MailStorage; -import static org.graalvm.component.installer.gds.rest.GDSRESTConnector.HEADER_VAL_GZIP; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.persist.MetadataLoader; -import org.graalvm.component.installer.persist.MetadataLoaderAdapter; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.remote.ProxyConnectionFactory.HttpConnectionException; -import org.graalvm.shadowed.org.json.JSONArray; -import org.graalvm.shadowed.org.json.JSONException; -import org.graalvm.shadowed.org.json.JSONObject; -import org.graalvm.shadowed.org.json.JSONTokener; - -import java.net.HttpURLConnection; -import java.util.zip.GZIPInputStream; - -/** - * Accesses GDS REST API, the catalogs referenced from it and turns them into a ComponentStorage. - * Currently just ONE single version of GraalVM is supported (see filter in {@link #acceptsVersion}. - * if more versions are selected, all their components are merged, as it is the case of - * multi-versioned catalogs (which are not actively deployed at the moment). - *

- * - * @author odouda - */ -public class GDSChannel extends GraalChannelBase { - private static final Logger LOG = Logger.getLogger(GDSChannel.class.getName()); - - private static final String HEADER_DOWNLOAD_CONFIG = "x-download-token"; - private static final String HEADER_CONTENT_ENCODING = "Content-Encoding"; - private static final String JSON_ITEMS = "items"; - private static final String JSON_EXC_CODE = "code"; - private static final String EXC_URL_END = "/content"; - private static final String EXC_CODE_UNVERIFIED_CONFIG = "UnverifiedToken"; - private static final String EXC_CODE_INVALID_CONFIG = "InvalidToken"; - private static final String EXC_CODE_UNACCEPTED = "InvalidLicenseAcceptance"; - - /** - * Helper to read/store GDS token settings. - */ - private GDSTokenStorage tokenStorage; - - private GDSRESTConnector gdsConnector; - - public GDSChannel(CommandInput aInput, Feedback aFeedback, ComponentRegistry aRegistry) { - super(aInput, aFeedback.withBundle(GDSChannel.class), aRegistry); - } - - void setTokenStorage(GDSTokenStorage s) { - this.tokenStorage = s; - } - - private String getToken() { - if (tokenStorage == null) { - tokenStorage = new GDSTokenStorage(fb, input); - } - return tokenStorage.getToken(); - } - - protected boolean needToken(ComponentInfo info) { - return !info.isImplicitlyAccepted(); - } - - /** - * GDS will require the user to supply an e-mail that can be used collected by the GDS services. - * - * @param info original info - * @param dn downloader instance - * @return configured downloader - */ - @Override - public FileDownloader configureDownloader(ComponentInfo info, FileDownloader dn) { - if (needToken(info)) { - String token = getToken(); - if (!SystemUtils.nonBlankString(token)) { - token = getToken(info.getLicensePath()); - } - dn.addRequestHeader(HEADER_DOWNLOAD_CONFIG, token); - } - getConnector().fillBasics(dn); - dn.setDownloadExceptionInterceptor(this::interceptDownloadException); - return dn; - } - - public IOException interceptDownloadException(IOException downloadException, FileDownloader fileDownloader) { - if (!(downloadException instanceof HttpConnectionException)) { - return downloadException; - } - HttpConnectionException hex = (HttpConnectionException) downloadException; - if (hex.getRetCode() < HttpURLConnection.HTTP_BAD_REQUEST) { - return (IOException) hex.getCause(); - } - String downloadURL = hex.getConnectionUrl().toString(); - if (!downloadURL.endsWith(EXC_URL_END)) { - return (IOException) hex.getCause(); - } - String licensePath = findLicensePath(downloadURL); - if (!SystemUtils.nonBlankString(licensePath)) { - return (IOException) hex.getCause(); - } - String code; - try { - code = new JSONObject(hex.getResponse()).getString(JSON_EXC_CODE); - } catch (JSONException ex) { - return (IOException) hex.getCause(); - } - String token = getToken(); - switch (code) { - case EXC_CODE_INVALID_CONFIG: - fb.output("ERR_WrongToken", token); - if (tokenStorage.getConfSource().equals(GDSTokenStorage.Source.FIL)) { - setToken(""); - } - token = getToken(licensePath); - break; - case EXC_CODE_UNVERIFIED_CONFIG: - fb.output("ERR_InvalidToken", token); - fb.acceptLine(false); - break; - case EXC_CODE_UNACCEPTED: - if (fileDownloader.getAttemptNr() == 1) { - getConnector().sendVerificationEmail(null, licensePath, token); - } - fb.output("PROMPT_VerifyEmailAddressEntry", fb.l10n("MSG_YourEmail")); - fb.acceptLine(false); - break; - default: - return (IOException) hex.getCause(); - } - fileDownloader.addRequestHeader(HEADER_DOWNLOAD_CONFIG, token); - return null; - } - - private String findLicensePath(String artifactURL) { - try { - for (String id : storage.listComponentIDs()) { - for (ComponentInfo info : storage.loadComponentMetadata(id)) { - if (info.getRemoteURL().toString().equals(artifactURL)) { - return info.getLicensePath(); - } - } - } - } catch (IOException ex) { - throw fb.withBundle(ComponentInstaller.class) - .failure("REGISTRY_ReadingComponentList", ex, ex.getLocalizedMessage()); - } - return null; - } - - private String getToken(String licensePath) { - fb.output("MSG_InputTokenEntry"); - fb.outputPart("PROMPT_InputTokenEntry"); - String token = fb.acceptLine(false); - if (!SystemUtils.nonBlankString(token)) { - String email = MailStorage.checkEmailAddress(receiveEmailAddress(), fb); - token = getConnector().sendVerificationEmail(email, licensePath, null); - saveToken(token); - fb.output("PROMPT_VerifyEmailAddressEntry", email); - fb.acceptLine(false); - } else { - saveToken(token); - } - return token; - } - - private void saveToken(String token) { - fb.output("MSG_ObtainedToken", token); - setToken(token); - } - - private void setToken(String token) { - try { - tokenStorage.setToken(token); - tokenStorage.save(); - } catch (IOException ex) { - fb.error("WARN_CannotSaveToken", ex, tokenStorage.getPropertiesPath()); - } - } - - @Override - public MetadataLoader interceptMetadataLoader(ComponentInfo info, MetadataLoader delegate) { - return new MetadataLoaderAdapter(delegate) { - @Override - public String getLicenseType() { - return null; - } - - @Override - public String getLicenseID() { - return null; - } - }; - } - - String receiveEmailAddress() { - String mail = input.optValue(GdsCommands.OPTION_EMAIL_ADDRESS); - if (mail == null) { - fb.output("MSG_EmailAddressEntry"); - fb.outputPart("PROMPT_EmailAddressEntry"); - mail = fb.acceptLine(false); - } - if (mail == null) { - throw fb.failure("ERR_EmailAddressMissing", null); - } - return mail; - } - - /** - * Initializes the component storage. - * - * @return merged storage. - * @throws IOException in case of an I/O error. - */ - @Override - protected ComponentStorage loadStorage() throws IOException { - FileDownloader fd = getConnector().obtainArtifacts(localRegistry.getJavaVersion()); - Path storagePath = fd.getLocalFile().toPath(); - List artifacts = loadArtifacts(storagePath, fd.getResponseHeader().get(HEADER_CONTENT_ENCODING)); - if (artifacts.isEmpty()) { - return throwEmptyStorage(); - } - return new GDSCatalogStorage(localRegistry, fb, storagePath.toUri().toURL(), artifacts); - } - - /** - * Loads the release index. Must be loaded from a local file. - * - * @param releasesIndexPath path to the downloaded releases index. - * @return list of entries in the index - * @throws IOException in case of I/O error. - */ - List loadArtifacts(Path releasesIndexPath, List contentEncoding) throws IOException { - if (edition == null) { - edition = localRegistry.getGraalCapabilities().get(CommonConstants.CAP_EDITION); - } - List result = new ArrayList<>(); - try (InputStreamReader urlReader = new InputStreamReader( - contentEncoding != null && contentEncoding.contains(HEADER_VAL_GZIP) - ? new GZIPInputStream(Files.newInputStream(releasesIndexPath)) - : Files.newInputStream(releasesIndexPath))) { - JSONTokener tokener = new JSONTokener(urlReader); - JSONObject obj = new JSONObject(tokener); - - JSONArray releases = obj.getJSONArray(JSON_ITEMS); - if (releases == null) { - // malformed releases file; - throw new IncompatibleException(fb.l10n("OLDS_InvalidReleasesFile")); - } - - Version v = localRegistry.getGraalVersion(); - for (Object k : releases) { - JSONObject jo = (JSONObject) k; - ArtifactParser e; - try { - e = new ArtifactParser(jo); - } catch (JSONException | IllegalArgumentException ex) { - fb.error("OLDS_ErrorReadingRelease", ex, k, ex.getLocalizedMessage()); - continue; - } - if (!localRegistry.getGraalCapabilities().get(CommonConstants.CAP_OS_NAME).equals(e.getOs())) { - LOG.log(Level.FINER, "Incorrect OS: {0}", k); - } else if (!localRegistry.getGraalCapabilities().get(CommonConstants.CAP_OS_ARCH).equals(e.getArch())) { - LOG.log(Level.FINER, "Incorrect Arch: {0}", k); - } else if (!localRegistry.getJavaVersion().equals(e.getJava())) { - LOG.log(Level.FINER, "Incorrect Java: {0}", k); - } else if (edition != null && !edition.equals(e.getEdition())) { - LOG.log(Level.FINER, "Incorrect edition: {0}", k); - } else if (!acceptsVersion(v, Version.fromString(e.getVersion()))) { - LOG.log(Level.FINER, "Old version: {0} != {1}", new Object[]{v, Version.fromString(e.getVersion()), e.getVersion()}); - } else if (e.getLabel() == null) { - LOG.log(Level.FINER, "Isn't installable component: {0}", new Object[]{e}); - } else { - result.add(e.asComponentInfo(getConnector(), fb)); - } - } - } - return result; - } - - GDSRESTConnector getConnector() { - if (gdsConnector == null) { - gdsConnector = new GDSRESTConnector( - getIndexURL().toString(), - fb, - input.getLocalRegistry().getGraalCapabilities() - .get(RELEASE_GDS_PRODUCT_ID_KEY), - input.getLocalRegistry().getGraalVersion()); - } - return gdsConnector; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannelFactory.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannelFactory.java deleted file mode 100644 index 4d9d6116c4bc..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSChannelFactory.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; - -import java.net.MalformedURLException; -import java.util.HashMap; -import java.util.Map; - -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.gds.GdsCommands; -import java.net.URL; - -/** - * Creates a Software channel for GDS REST API. The URL is: - *

    - *
  • rest://path - *
  • rest:protocol://path - *
- * - * @author odouda - */ -public class GDSChannelFactory implements SoftwareChannel.Factory { - private static final String PROTOCOL_GDS_REST_PREFIX = "rest:"; // NOI18N - private static final String PROTOCOL_HTTTPS_PREFIX = "https:"; // NOI18N - - private static final Map OPTIONS = new HashMap<>(); - - private Feedback feedback; - - static { - OPTIONS.put(GdsCommands.OPTION_GDS_CONFIG, "s"); - OPTIONS.put(GdsCommands.LONG_OPTION_GDS_CONFIG, GdsCommands.OPTION_GDS_CONFIG); - OPTIONS.put(GdsCommands.OPTION_SHOW_TOKEN, ""); - OPTIONS.put(GdsCommands.LONG_OPTION_SHOW_TOKEN, GdsCommands.OPTION_SHOW_TOKEN); - OPTIONS.put(GdsCommands.OPTION_REVOKE_TOKEN, "s"); - OPTIONS.put(GdsCommands.LONG_OPTION_REVOKE_TOKEN, GdsCommands.OPTION_REVOKE_TOKEN); - OPTIONS.put(GdsCommands.OPTION_REVOKE_ALL_TOKENS, "s"); - OPTIONS.put(GdsCommands.LONG_OPTION_REVOKE_ALL_TOKENS, GdsCommands.OPTION_REVOKE_ALL_TOKENS); - OPTIONS.put(GdsCommands.OPTION_REVOKE_CURRENT_TOKEN, ""); - OPTIONS.put(GdsCommands.LONG_OPTION_REVOKE_CURRENT_TOKEN, GdsCommands.OPTION_REVOKE_CURRENT_TOKEN); - } - - @Override - public SoftwareChannel createChannel(SoftwareChannelSource source, CommandInput input, Feedback output) { - feedback = output; - String urlString = source.getLocationURL(); - if (!urlString.startsWith(PROTOCOL_GDS_REST_PREFIX)) { - return null; - } - String rest = urlString.substring(PROTOCOL_GDS_REST_PREFIX.length()); - URL u; - try { - if (rest.startsWith("http") || rest.startsWith("file:") || rest.startsWith("test:")) { - u = SystemUtils.toURL(rest); - } else { - u = SystemUtils.toURL(PROTOCOL_HTTTPS_PREFIX + rest); - } - } catch (MalformedURLException ex) { - throw output.failure("YUM_InvalidLocation", ex, urlString, ex.getLocalizedMessage()); - } - GDSChannel ch = new GDSChannel(input, output, input.getLocalRegistry()); - ch.setIndexURL(u); - ch.setEdition(source.getParameter("edition")); - return ch; - } - - @Override - public Map globalOptions() { - return OPTIONS; - } - - @Override - public String globalOptionsHelp() { - return feedback.l10n("GDS_REST_ExtraOptionsHelp"); - } - - @Override - public void init(CommandInput input, Feedback output) { - feedback = output.withBundle(this.getClass()); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSRESTConnector.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSRESTConnector.java deleted file mode 100644 index 6417c56c396f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSRESTConnector.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.remote.FileDownloader; -import org.graalvm.component.installer.URLConnectionFactory; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.remote.ProxyConnectionFactory; -import org.graalvm.shadowed.org.json.JSONException; -import org.graalvm.shadowed.org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * This class serves as GDS REST Endpoint connector for communication with service. - * - * @author odouda - */ -class GDSRESTConnector { - static final String ENDPOINT_ARTIFACTS = "artifacts/"; - static final String ENDPOINT_DOWNLOAD = "/content"; - static final String ENDPOINT_PRODUCTS = "products"; - static final String ENDPOINT_LICENSE = "licenses/"; - static final String ENDPOINT_LICENSE_ACCEPT = "licenseAcceptance/"; - static final String ENDPOINT_REVOKE_TOKEN = "tokenRequests"; - - static final String QUERRY_DISPLAY_NAME = "displayName"; - static final String QUERRY_PRODUCT_NAME = "GraalVM"; - static final String QUERRY_PRODUCT = "productId"; - static final String QUERRY_METADATA = "metadata"; - static final String QUERRY_ARCH = "arch:"; - static final String QUERRY_OS = "os:"; - static final String QUERRY_TYPE = "type:"; - static final String QUERRY_TYPE_CORE = QUERRY_TYPE + "core"; - static final String QUERRY_TYPE_COMP = QUERRY_TYPE + "component"; - static final String QUERRY_RELEASE = "release:"; - static final String QUERRY_JAVA = "java:"; - static final String QUERRY_LIMIT_KEY = "limit"; - static final String QUERRY_LIMIT_VAL = "1000"; - - public static final String HEADER_VAL_GZIP = "gzip"; - static final String HEADER_ENCODING = "Accept-Encoding"; - static final String HEADER_USER_AGENT = "User-Agent"; - final String gdsUserAgent; - - final String baseURL; - final Feedback feedback; - final Map> params = new HashMap<>(); - - final String productId; - - GDSRESTConnector(String baseURL, Feedback feedback, String productId, Version gvmVersion) { - if (baseURL == null || baseURL.isBlank()) { - throw new IllegalArgumentException("Base URL String can't be empty."); - } - URL url = null; - try { - url = SystemUtils.toURL(baseURL); - } catch (MalformedURLException ex) { - throw new IllegalArgumentException("Base URL String must be convertible to URL."); - } - this.baseURL = url.toString(); - if (feedback == null) { - throw new IllegalArgumentException("Feedback can't be null."); - } - this.feedback = feedback.withBundle(GDSRESTConnector.class); - if (productId == null || productId.isBlank()) { - throw new IllegalArgumentException("Product ID can't be empty."); - } - this.productId = productId; - if (gvmVersion == null || gvmVersion == Version.NO_VERSION) { - throw new IllegalArgumentException("Version can't be empty."); - } - this.gdsUserAgent = String.format("GVM/%s (arch:%s; os:%s; java:%s)", - gvmVersion.toString(), - SystemUtils.ARCH.sysName(), - SystemUtils.OS.sysName(), - SystemUtils.getJavaMajorVersion()); - } - - Map> getParams() { - return params; - } - - public void revokeToken(String token) { - try { - GDSRequester tr = getGDSRequester(baseURL + ENDPOINT_REVOKE_TOKEN, token); - tr.revokeToken(token); - } catch (IOException ex) { - throw feedback.failure("ERR_VerificationEmail", ex, feedback.l10n("MSG_YourEmail")); - } - } - - public void revokeTokens(String email) { - try { - GDSRequester tr = getGDSRequester(baseURL + ENDPOINT_REVOKE_TOKEN, email); - tr.revokeTokens(email); - } catch (IOException ex) { - throw feedback.failure("ERR_VerificationEmail", ex, email); - } - } - - public FileDownloader obtainComponents() { - fillMetaComponent(); - return obtainArtifacts(); - } - - public FileDownloader obtainComponents(String releaseVersion) { - fillMetaRelease(releaseVersion); - return obtainComponents(); - } - - public FileDownloader obtainReleases(String javaVersion) { - fillMetaJava(javaVersion); - return obtainReleases(); - } - - public FileDownloader obtainReleases() { - fillMetaCore(); - return obtainArtifacts(); - } - - public FileDownloader obtainArtifacts(String javaVersion) { - fillMetaJava(javaVersion); - return obtainArtifacts(); - } - - public FileDownloader obtainArtifacts() { - fillArtifacts(); - return obtain(ENDPOINT_ARTIFACTS); - } - - public FileDownloader obtainProduct() { - fillDisplayName(); - return obtain(ENDPOINT_PRODUCTS); - } - - public String sendVerificationEmail(String email, String licAddr, String config) { - assert (SystemUtils.nonBlankString(email) && config == null) || (SystemUtils.nonBlankString(config) && email == null); - String licID = licAddr.substring(licAddr.lastIndexOf("/") + 1); - String acceptLicLink = baseURL + ENDPOINT_LICENSE_ACCEPT; - String token = config; - try { - GDSRequester tr = getGDSRequester(acceptLicLink, licID); - token = email != null ? tr.obtainConfig(email) : tr.acceptLic(config); - } catch (IOException ex) { - throw feedback.failure("ERR_VerificationEmail", ex, email == null ? feedback.l10n("MSG_YourEmail") : email); - } - return token; - } - - public String makeLicenseURL(String licenseId) { - return baseURL + ENDPOINT_LICENSE + licenseId; - } - - public String makeArtifactsURL(String javaVersion) { - fillArtifacts(); - fillMetaJava(javaVersion); - String out = SystemUtils.buildUrlStringWithParameters(baseURL + ENDPOINT_ARTIFACTS, getParams()); - params.clear(); - return out; - } - - public String makeReleaseCatalogURL(String releaseVersion, String javaVersion) { - fillArtifacts(); - fillMetaJava(javaVersion); - fillMetaRelease(releaseVersion); - String out = SystemUtils.buildUrlStringWithParameters(baseURL + ENDPOINT_ARTIFACTS, getParams()); - params.clear(); - return out; - } - - URL makeArtifactDownloadURL(String id) { - String url = baseURL + ENDPOINT_ARTIFACTS + id + ENDPOINT_DOWNLOAD; - try { - return SystemUtils.toURL(url); - } catch (MalformedURLException ex) { - feedback.error("ERR_MalformedArtifactUrl", ex, url); - } - return null; - } - - protected FileDownloader obtain(String endpoint) { - addParam(QUERRY_LIMIT_KEY, QUERRY_LIMIT_VAL); - try { - FileDownloader dn = new FileDownloader( - feedback.l10n("OLDS_ReleaseFile"), - SystemUtils.toURL(SystemUtils.buildUrlStringWithParameters(baseURL + endpoint, getParams())), - feedback); - fillBasics(dn); - dn.download(); - return dn; - } catch (IOException ex) { - throw feedback.failure("ERR_CouldNotLoadGDS", ex, baseURL, ex.getLocalizedMessage()); - } finally { - params.clear(); - } - } - - private void fillArtifacts() { - fillProductId(); - fillMetaArchAndOS(); - } - - private void fillProductId() { - addParam(QUERRY_PRODUCT, productId); - } - - private void fillDisplayName() { - addParam(QUERRY_DISPLAY_NAME, QUERRY_PRODUCT_NAME); - } - - private void fillMetaArchAndOS() { - addParam(QUERRY_METADATA, QUERRY_ARCH + SystemUtils.ARCH.get().getName()); - addParam(QUERRY_METADATA, QUERRY_OS + SystemUtils.OS.get().getName()); - } - - private void fillMetaCore() { - addParam(QUERRY_METADATA, QUERRY_TYPE_CORE); - } - - private void fillMetaComponent() { - addParam(QUERRY_METADATA, QUERRY_TYPE_COMP); - } - - private void fillMetaRelease(String releaseVersion) { - addParam(QUERRY_METADATA, QUERRY_RELEASE + releaseVersion); - } - - private void fillMetaJava(String javaVersion) { - addParam(QUERRY_METADATA, QUERRY_JAVA + "jdk" + javaVersion); - } - - private void addParam(String key, String value) { - params.computeIfAbsent(key, k -> new ArrayList<>()).add(value); - } - - public void fillBasics(FileDownloader fd) { - fd.addRequestHeader(HEADER_USER_AGENT, gdsUserAgent); - fd.addRequestHeader(HEADER_ENCODING, HEADER_VAL_GZIP); - } - - GDSRequester getGDSRequester(String acceptLicLink, String licID) throws MalformedURLException { - return new GDSRequester(SystemUtils.toURL(acceptLicLink), licID); - } - - class GDSRequester { - static final String GENERATE_CONFIG = "GENERATE_TOKEN_AND_ACCEPT_LICENSE"; - static final String ACCEPT_LICENSE = "ACCEPT_LICENSE_USING_TOKEN"; - static final String REVOKE_TOKEN = "REVOKE"; - - static final String HEADER_CONTENT = "Content-Type"; - static final String HEADER_VAL_JSON = "application/json"; - - static final String REQUEST_CONFIG_BODY = "{\"type\":\"%s\",\"email\":\"%s\",\"licenseId\":\"%s\"}"; - static final String REQUEST_ACCEPT_BODY = "{\"type\":\"%s\",\"token\":\"%s\",\"licenseId\":\"%s\"}"; - static final String REQUEST_REVOKE_BODY = "{\"type\":\"%s\",\"downloadToken\":\"%s\"}"; - static final String REQUEST_REVOKE_ALL_BODY = "{\"type\":\"%s\",\"email\":\"%s\"}"; - - static final String JSON_CONFIG = "token"; - - final URL url; - final String id; - URLConnectionFactory factory; - - GDSRequester(URL url, String id) { - this.url = url; - this.id = id; - } - - public String obtainConfig(String email) throws IOException { - String config = null; - URLConnection connector = getConnectionFactory().createConnection(url, createConfigCallBack(Request.GENERATE, email)); - String response = null; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(connector.getInputStream()))) { - response = reader.lines().collect(Collectors.joining()); - config = new JSONObject(response).getString(JSON_CONFIG); - } catch (JSONException ex) { - throw feedback.failure("ERR_ResponseBody", ex, response); - } - if (!SystemUtils.nonBlankString(config)) { - throw feedback.failure("ERR_ResponseBody", null, response); - } - return config; - } - - public String acceptLic(String config) throws IOException { - return connect(Request.ACCEPT, config); - } - - public void revokeTokens(String email) throws IOException { - connect(Request.REVOKE_ALL, email); - } - - public void revokeToken(String token) throws IOException { - connect(Request.REVOKE, token); - } - - private String connect(Request req, String content) throws IOException { - getConnectionFactory().createConnection(url, createConfigCallBack(req, content)).connect(); - return content; - } - - private String generateRequestBody(Request req, String content) { - return String.format(getRequestFormat(req), - getRequestName(req), - content, - id); - } - - private String getRequestFormat(Request req) { - switch (req) { - case REVOKE_ALL: - return REQUEST_REVOKE_ALL_BODY; - case REVOKE: - return REQUEST_REVOKE_BODY; - case ACCEPT: - return REQUEST_ACCEPT_BODY; - case GENERATE: - return REQUEST_CONFIG_BODY; - } - return null; - } - - private String getRequestName(Request req) { - switch (req) { - case REVOKE_ALL: - case REVOKE: - return REVOKE_TOKEN; - case ACCEPT: - return ACCEPT_LICENSE; - case GENERATE: - return GENERATE_CONFIG; - } - return null; - } - - private URLConnectionFactory.Configure createConfigCallBack(Request req, String content) { - return (URLConnection connector) -> { - connector.addRequestProperty(HEADER_USER_AGENT, gdsUserAgent); - connector.setDoOutput(true); - connector.setRequestProperty(HEADER_CONTENT, HEADER_VAL_JSON); - try (OutputStreamWriter out = new OutputStreamWriter(connector.getOutputStream())) { - out.append(generateRequestBody(req, content)); - } - }; - } - - URLConnectionFactory getConnectionFactory() throws MalformedURLException { - if (factory == null) { - factory = new ProxyConnectionFactory(feedback, SystemUtils.toURL(baseURL)); - } - return factory; - } - } - - enum Request { - GENERATE, - ACCEPT, - REVOKE, - REVOKE_ALL - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSTokenStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSTokenStorage.java deleted file mode 100644 index 0ed70eb57674..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/gds/rest/GDSTokenStorage.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.gds.rest; - -import org.graalvm.component.installer.CommandInput; -import static org.graalvm.component.installer.CommonConstants.SYSPROP_USER_HOME; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Properties; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.gds.GdsCommands; -import static org.graalvm.component.installer.CommonConstants.PATH_GDS_CONFIG; -import org.graalvm.component.installer.SystemUtils; -import java.nio.file.attribute.PosixFilePermission; -import java.util.Set; -import static org.graalvm.component.installer.CommonConstants.PATH_USER_GU; -import java.io.File; -import java.util.Map; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.gds.MailStorage; - -/** - * - * @author odouda - */ -public class GDSTokenStorage { - - static final String GRAAL_EE_DOWNLOAD_TOKEN = "GRAAL_EE_DOWNLOAD_TOKEN"; - private final Feedback feedback; - private final CommandInput input; - private final Path propertiesPath; - - private Source tokenSource = Source.NON; - private Properties properties; - private boolean changed; - - public GDSTokenStorage(Feedback feedback, CommandInput input) { - this.feedback = feedback.withBundle(GDSTokenStorage.class); - this.input = input; - propertiesPath = Path.of(System.getProperty(SYSPROP_USER_HOME), PATH_USER_GU, PATH_GDS_CONFIG); - } - - Path getPropertiesPath() { - return propertiesPath; - } - - public Source getConfSource() { - return tokenSource; - } - - private Properties load() { - if (properties != null) { - return properties; - } - return properties = load(getPropertiesPath()); - } - - private Properties load(Path propsPath) { - Properties props = new Properties(); - if (Files.exists(propsPath)) { - try (InputStream is = Files.newInputStream(propsPath)) { - props.load(is); - } catch (IllegalArgumentException | IOException ex) { - feedback.error("ERR_CouldNotLoadToken", ex, propsPath, ex.getLocalizedMessage()); - } - } - return props; - } - - public String getToken() { - String token = getCmdToken(); - if (SystemUtils.nonBlankString(token)) { - tokenSource = Source.CMD; - return token; - } - token = getEnvToken(); - if (SystemUtils.nonBlankString(token)) { - tokenSource = Source.ENV; - return token; - } - token = getFileToken(); - if (SystemUtils.nonBlankString(token)) { - tokenSource = Source.FIL; - return token; - } - tokenSource = Source.NON; - return null; - } - - private String getCmdToken() { - String userFile = getCmdFile(); - if (!SystemUtils.nonBlankString(userFile)) { - return null; - } - return load(SystemUtils.fromUserString(userFile)).getProperty(GRAAL_EE_DOWNLOAD_TOKEN); - } - - private String getCmdFile() { - return input.optValue(GdsCommands.OPTION_GDS_CONFIG); - } - - private String getEnvToken() { - return input.getParameter(GRAAL_EE_DOWNLOAD_TOKEN, false); - } - - private String getFileToken() { - return load().getProperty(GRAAL_EE_DOWNLOAD_TOKEN); - } - - public void setToken(String token) { - if (token == null) { - throw new IllegalArgumentException("Download token cannot be null."); - } - String p = getFileToken(); - if (token.equals(p)) { - return; - } - properties.setProperty(GRAAL_EE_DOWNLOAD_TOKEN, token); - changed = true; - } - - public void save() throws IOException { - Path propsPath = getPropertiesPath(); - if (!changed || properties == null || propsPath == null) { - return; - } - Path parent = propsPath.getParent(); - if (parent == null) { - // cannot happen, but Spotbugs keeps yelling - return; - } - Files.createDirectories(parent); - if (SystemUtils.isWindows()) { - File file = parent.toFile(); - file.setReadable(false, false); - file.setExecutable(false, false); - file.setWritable(false, false); - file.setReadable(true); - file.setExecutable(true); - file.setWritable(true); - } else { - Files.setPosixFilePermissions(parent, Set.of(PosixFilePermission.OWNER_READ, - PosixFilePermission.OWNER_WRITE, - PosixFilePermission.OWNER_EXECUTE)); - } - try (OutputStream os = Files.newOutputStream(propsPath)) { - properties.store(os, null); - } - if (SystemUtils.isWindows()) { - File file = propsPath.toFile(); - file.setReadable(false, false); - file.setExecutable(false, false); - file.setWritable(false, false); - file.setReadable(true); - file.setWritable(true); - } else { - Files.setPosixFilePermissions(propsPath, - Set.of(PosixFilePermission.OWNER_READ, - PosixFilePermission.OWNER_WRITE)); - } - changed = false; - } - - public static void printToken(Feedback feedback, CommandInput input) { - new GDSTokenStorage(feedback, input).printToken(); - } - - public static void revokeToken(Feedback feedback, CommandInput input, String token) { - new GDSTokenStorage(feedback, input).revokeToken(token); - } - - public static void revokeAllTokens(Feedback feedback, CommandInput input, String email) { - new GDSTokenStorage(feedback, input).revokeAllTokens(email); - } - - public void revokeAllTokens(String email) { - GDSRESTConnector connector = makeConnector(); - if (connector == null) { - feedback.message("MSG_NoGDSAddress"); - return; - } - String m = MailStorage.checkEmailAddress(email, feedback); - if (m == null || m.isEmpty()) { - feedback.message("MSG_NoEmail"); - return; - } - connector.revokeTokens(m); - feedback.message("MSG_AcceptRevoke"); - } - - public void revokeToken(String token) { - GDSRESTConnector connector = makeConnector(); - if (connector == null) { - feedback.message("MSG_NoGDSAddress"); - return; - } - String t = token; - if (t == null || t.isEmpty()) { - t = getFileToken(); - if (t == null || t.isEmpty()) { - feedback.message("MSG_NoRevokableToken"); - return; - } - removeFileToken(); - } - connector.revokeToken(t); - feedback.message("MSG_AcceptRevoke"); - } - - GDSRESTConnector makeConnector() { - Map caps = input.getLocalRegistry().getGraalCapabilities(); - String releaseCatalog = caps.get(CommonConstants.RELEASE_CATALOG_KEY); - if (releaseCatalog == null || releaseCatalog.isEmpty()) { - return null; - } - String[] catalogs = releaseCatalog.split("\\|"); - String catalog = null; - for (String c : catalogs) { - if (c.contains("rest://")) { - catalog = "https" + c.substring(c.indexOf("rest://") + 4); - } - } - if (catalog == null || catalog.isEmpty()) { - return null; - } - return new GDSRESTConnector(catalog, feedback, caps.get(CommonConstants.RELEASE_GDS_PRODUCT_ID_KEY), input.getLocalRegistry().getGraalVersion()); - } - - public void removeFileToken() { - load().remove(GRAAL_EE_DOWNLOAD_TOKEN); - changed = true; - try { - save(); - } catch (IOException ex) { - feedback.error("ERR_CouldNotRemoveToken", ex); - } - } - - public void printToken() { - String token = getToken(); - String msg = tokenSource == Source.NON ? "MSG_EmptyToken" : "MSG_PrintToken"; - String source = ""; - switch (tokenSource) { - case ENV: - source = feedback.l10n("MSG_PrintTokenEnv", GRAAL_EE_DOWNLOAD_TOKEN); - break; - case CMD: - source = feedback.l10n("MSG_PrintTokenCmdFile", getCmdFile()); - break; - case FIL: - source = feedback.l10n("MSG_PrintTokenFile", getPropertiesPath().toString()); - break; - default: - // NOOP - break; - } - feedback.output(msg, token, source); - } - - public enum Source { - NON, - ENV, - CMD, - FIL - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/Bundle.properties deleted file mode 100644 index 7b5387c9ed1c..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/Bundle.properties +++ /dev/null @@ -1,5 +0,0 @@ -# {0} - component ID -# {1} - component version -LICENSE_Path_translation=LICENSE-{0}-{1} -ERROR_LoadLicense=Could not load license from archive path {0}: {1} -ERROR_LicenseNotFound=License not found in archive: {0} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarArchive.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarArchive.java deleted file mode 100644 index ba119d2e958c..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarArchive.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.jar; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.channels.ReadableByteChannel; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.zip.CRC32; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.model.ComponentInfo; - -/** - * - * @author sdedic - */ -public class JarArchive implements Archive { - private static final int CHECKSUM_BUFFER_SIZE = 1024 * 32; - - private final JarFile jarFile; - - public JarArchive(JarFile jarFile) { - this.jarFile = jarFile; - } - - public FileEntry getEntry(String path) { - return getJarEntry(path); - } - - public FileEntry getJarEntry(String path) { - JarEntry e = jarFile.getJarEntry(path); - return e == null ? null : new JarEntryImpl(e); - } - - @Override - public Iterator iterator() { - return new EntryIterator(jarFile.entries()); - } - - @Override - public void close() throws IOException { - } - - @Override - public InputStream getInputStream(FileEntry e) throws IOException { - return jarFile.getInputStream(((JarEntryImpl) e).e); - } - - @Override - public boolean checkContentsMatches(ReadableByteChannel bc, FileEntry entry) throws IOException { - ByteBuffer bb = ByteBuffer.allocate(CHECKSUM_BUFFER_SIZE); - CRC32 crc = new CRC32(); - while (bc.read(bb) >= 0) { - bb.flip(); - crc.update(bb); - bb.clear(); - } - return crc.getValue() == ((JarEntryImpl) entry).e.getCrc(); - } - - @Override - public void completeMetadata(ComponentInfo info) throws IOException { - // no op - } - - /** - * Always returns true. Signer JARs are automatically verified on open - * - * @return true - */ - @Override - public boolean verifyIntegrity(CommandInput input) { - return true; - } - - private static class EntryIterator implements Iterator { - private final Enumeration enEntries; - - EntryIterator(Enumeration enEntries) { - this.enEntries = enEntries; - } - - @Override - public boolean hasNext() { - return enEntries.hasMoreElements(); - } - - @Override - public JarEntryImpl next() { - return new JarEntryImpl(enEntries.nextElement()); - } - } - - private static class JarEntryImpl implements FileEntry { - private final JarEntry e; - - JarEntryImpl(JarEntry e) { - this.e = e; - } - - @Override - public String getName() { - return e.getName(); - } - - @Override - public boolean isDirectory() { - return e.isDirectory(); - } - - @Override - public long getSize() { - return e.getSize(); - } - - @Override - public boolean isSymbolicLink() { - return false; - } - - @Override - public String getLinkTarget() throws IOException { - throw new IllegalStateException("Not a symbolic link"); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarMetaLoader.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarMetaLoader.java deleted file mode 100644 index 406daf0aeb25..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/jar/JarMetaLoader.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.jar; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.function.Function; -import java.util.jar.Attributes; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.util.stream.Collectors; -import org.graalvm.component.installer.Archive; -import static org.graalvm.component.installer.BundleConstants.META_INF_PATH; -import static org.graalvm.component.installer.BundleConstants.META_INF_PERMISSIONS_PATH; -import static org.graalvm.component.installer.BundleConstants.META_INF_SYMLINKS_PATH; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.ComponentPackageLoader; - -/** - * - * @author sdedic - */ -public class JarMetaLoader extends ComponentPackageLoader { - private final JarFile jarFile; - @SuppressWarnings("unused") - // TODO: refactor construction - private final Feedback fb; - - public JarMetaLoader(JarFile jarFile, Feedback feedback) throws IOException { - this(jarFile, null, feedback); - } - - public JarMetaLoader(JarFile jarFile, String serial, Feedback feedback) throws IOException { - super(serial, new ManifestValues(jarFile), feedback); - this.jarFile = jarFile; - this.fb = feedback.withBundle(JarMetaLoader.class); - } - - private static class ManifestValues implements Function { - private final Manifest mf; - private final Attributes mainAttributes; - - ManifestValues(JarFile jf) throws IOException { - this.mf = jf.getManifest(); - this.mainAttributes = mf == null ? null : mf.getMainAttributes(); - } - - @Override - public String apply(String t) { - return mainAttributes == null ? null : mainAttributes.getValue(t); - } - - } - - @Override - public void close() throws IOException { - super.close(); - jarFile.close(); - } - - @Override - public Archive getArchive() { - return new JarArchive(jarFile); - } - - @Override - public Map loadPermissions() throws IOException { - JarEntry permEntry = jarFile.getJarEntry(META_INF_PERMISSIONS_PATH); - if (permEntry == null) { - return Collections.emptyMap(); - } - try (BufferedReader r = new BufferedReader(new InputStreamReader( - jarFile.getInputStream(permEntry), "UTF-8"))) { - Map permissions = parsePermissions(r); - return permissions; - } - } - - @Override - public void loadPaths() { - ComponentInfo cinfo = getComponentInfo(); - Set emptyDirectories = new HashSet<>(); - List files = new ArrayList<>(); - for (JarEntry en : Collections.list(jarFile.entries())) { - String eName = en.getName(); - if (eName.startsWith(META_INF_PATH)) { - continue; - } - int li = eName.lastIndexOf("/", en.isDirectory() ? eName.length() - 2 : eName.length() - 1); - if (li > 0) { - emptyDirectories.remove(eName.substring(0, li + 1)); - } - if (en.isDirectory()) { - // directory names always come first - emptyDirectories.add(eName); - } else { - files.add(eName); - } - } - addFiles(new ArrayList<>(emptyDirectories)); - // sort empty directories first - Collections.sort(files); - cinfo.addPaths(files); - addFiles(files); - } - - @Override - public Map loadSymlinks() throws IOException { - JarEntry symEntry = jarFile.getJarEntry(META_INF_SYMLINKS_PATH); - if (symEntry == null) { - return Collections.emptyMap(); - } - Properties links = new Properties(); - try (InputStream istm = jarFile.getInputStream(symEntry)) { - links.load(istm); - } - return parseSymlinks(links); - } - - @Override - public String getLicenseID() { - String licPath = getLicensePath(); - if (licPath == null) { - return null; - } - if (SystemUtils.isRemotePath(licPath)) { - return super.getLicenseID(); - } - JarEntry je = jarFile.getJarEntry(licPath); - if (je == null) { - throw fb.failure("ERROR_LicenseNotFound", null, getLicensePath()); - } - try (BufferedReader r = new BufferedReader(new InputStreamReader( - jarFile.getInputStream(je), "UTF-8"))) { - String text = r.lines().collect(Collectors.joining("\n")); - return SystemUtils.digestString(text, false); - } catch (IOException ex) { - throw fb.failure("ERROR_LoadLicense", ex, getLicensePath(), ex.getLocalizedMessage()); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Bundle.properties deleted file mode 100644 index a6b20b546cc7..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Bundle.properties +++ /dev/null @@ -1,6 +0,0 @@ -ComponentStabilityLevel_supported=Supported -ComponentStabilityLevel_earlyadopter=Early adopter -ComponentStabilityLevel_experimental=Experimental -# Need to have non-empty display string, to allow "sane" parsing of of output. -ComponentStabilityLevel_undefined=- -ComponentStabilityLevel_experimental_earlyadopter=Early adopter (experimental) diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/CatalogContents.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/CatalogContents.java deleted file mode 100644 index 56c865af7629..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/CatalogContents.java +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.IOException; -import java.nio.file.NoSuchFileException; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.Version; - -/** - * - * @author sdedic - */ -public final class CatalogContents implements ComponentCatalog { - private static final List NONE = new ArrayList<>(); - - private final ComponentStorage storage; - private final Feedback env; - private final Map> components = new HashMap<>(); - private final Version graalVersion; - private final ComponentRegistry installed; - private final Verifier verifier; - private final Verifier capVerifier; - private final DownloadInterceptor downloadInterceptor; - - private boolean remoteEnabled = true; - - /** - * Allows update to a newer distribution, not just patches. This will cause components from - * newer GraalVM distributions to be accepted, even though it means a reinstall. Normally just - * minor patches are accepted so the current component can be replaced. - */ - private boolean allowDistUpdate; - - public CatalogContents(Feedback env, ComponentStorage storage, ComponentRegistry inst) { - this(env, storage, inst, inst.getGraalVersion()); - } - - public CatalogContents(Feedback env, ComponentStorage storage, ComponentRegistry inst, Version version) { - this.storage = storage; - this.env = env.withBundle(Feedback.class); - this.verifier = new Verifier(env, inst, this); - this.capVerifier = new Verifier(env, inst, this); - this.graalVersion = version; - this.installed = inst; - - verifier.ignoreExisting(true); - verifier.setSilent(true); - verifier.setCollectErrors(true); - verifier.setVersionMatch(graalVersion.match(Version.Match.Type.SATISFIES)); - - // just verify required capabilities: - capVerifier.ignoreExisting(true); - capVerifier.setSilent(true); - capVerifier.setCollectErrors(true); - // ignore graal version, compare just the required capabilities. - capVerifier.setVersionMatch(Version.NO_VERSION.match(Version.Match.Type.GREATER)); - - if (storage instanceof DownloadInterceptor) { - this.downloadInterceptor = (DownloadInterceptor) storage; - } else { - this.downloadInterceptor = (a, b) -> b; - } - } - - public boolean compatibleVersion(ComponentInfo info) { - // excludes components that depend on obsolete versions - // excludes components that depend on - Version v = info.getVersion(); - Version gv = graalVersion; - if (allowDistUpdate) { - return gv.updatable().compareTo(v.updatable()) <= 0; - } else { - Version giv = gv.installVersion(); - Version civ = v.installVersion(); - return giv.equals(civ); - } - } - - public void setRemoteEnabled(boolean remoteEnabled) { - this.remoteEnabled = remoteEnabled; - } - - @Override - public boolean isRemoteEnabled() { - return remoteEnabled; - } - - private ComponentInfo compatibleComponent(List cis, Version.Match versionSelect, boolean fallback) { - if (cis == null) { - return null; - } - ComponentInfo first = null; - Version.Match vm = versionMatch(versionSelect, cis); - boolean explicit = versionSelect != null && versionSelect.getType() != Version.Match.Type.MOSTRECENT; - for (int i = cis.size() - 1; i >= 0; i--) { - ComponentInfo ci = cis.get(i); - if (first == null) { - first = ci; - } - Version v = ci.getVersion(); - if (!vm.test(v)) { - continue; - } - if (verifier.validateRequirements(ci).hasErrors()) { - continue; - } - if (explicit || compatibleVersion(ci)) { - return ci; - } - } - return fallback ? first : null; - } - - /** - * @return True, if components from newer distributions are allowed. - */ - @Override - public boolean isAllowDistUpdate() { - return allowDistUpdate; - } - - /** - * Enables components from newer distributions. - * - * @param allowDistUpdate - */ - @Override - public void setAllowDistUpdate(boolean allowDistUpdate) { - this.allowDistUpdate = allowDistUpdate; - } - - private Version.Match versionMatch(Version.Match m, List infos) { - if (m != null && m.getType() != Version.Match.Type.MOSTRECENT) { - return resolveMatch(m, infos, env); - } - Version v = m == null ? graalVersion : m.getVersion(); - if (v == Version.NO_VERSION) { - v = graalVersion; - } - return v.match(allowDistUpdate ? Version.Match.Type.INSTALLABLE : Version.Match.Type.COMPATIBLE); - } - - private static Version.Match resolveMatch(Version.Match vm, List comps, Feedback f) { - if (vm == null) { - return null; - } - List vers = new ArrayList<>(comps.size()); - for (ComponentInfo ci : comps) { - vers.add(ci.getVersion()); - } - Collections.sort(vers); - return vm.resolveWildcards(vers, f); - } - - @Override - public ComponentInfo findComponentMatch(String id, Version.Match vm, boolean exact) { - if (id == null) { - return null; - } - List infos = doLoadComponents(id, false, exact); - if (infos == null) { - return null; - } - return compatibleComponent(infos, vm, false); - } - - @Override - public String shortenComponentId(ComponentInfo info) { - String id = info.getId(); - if (id.startsWith(CommonConstants.GRAALVM_CORE_PREFIX)) { - int l = CommonConstants.GRAALVM_CORE_PREFIX.length(); - if (id.length() == l) { - return CommonConstants.GRAALVM_CORE_SHORT_ID; - } - if (id.charAt(l) != '.' && id.length() > l + 1) { - return id; - } - String shortId = id.substring(l + 1); - // special case: if the component is local, do not go to catalogs. - if (info.getRemoteURL() == null) { - return shortId; - } - try { - Collection regs = doLoadComponents(shortId, false, false); - if (regs == null) { - return shortId; - } - boolean success = true; - for (ComponentInfo reg : regs) { - if (!reg.getId().equals(id)) { - success = false; - break; - } - } - if (success) { - return shortId; - } - } catch (FailedOperationException ex) { - // ambiguous, ignore - } - } - return id; - } - - @Override - public Collection getComponentIDs() { - try { - return storage.listComponentIDs(); - } catch (IOException ex) { - throw env.failure("REGISTRY_ReadingComponentList", ex, ex.getLocalizedMessage()); - } - } - - private String findAbbreviatedId(String id) { - String candidate = null; - String lcid = id.toLowerCase(Locale.ENGLISH); - String end = "." + lcid; // NOI18N - Collection ids = getComponentIDs(); - String ambiguous = null; - for (String s : ids) { - String lcs = s.toLowerCase(Locale.ENGLISH); - if (lcs.equals(lcid)) { - return s; - } - if (lcs.endsWith(end)) { - if (candidate != null) { - ambiguous = s; - } else { - candidate = s; - } - } - } - if (ambiguous != null) { - throw env.failure("COMPONENT_AmbiguousIdFound", null, candidate, ambiguous); - } - return candidate; - } - - @Override - public Collection loadComponents(String id, Version.Match vmatch, boolean filelist) { - List v = doLoadComponents(id, filelist, false); - if (v == null) { - return null; - } - if (vmatch.getType() == Version.Match.Type.MOSTRECENT) { - ComponentInfo comp = compatibleComponent(v, versionMatch(vmatch, v), true); - return comp == null ? Collections.emptyList() : Collections.singleton(comp); - } - Version.Match resolvedMatch = resolveMatch(vmatch, v, env); - List versions = new ArrayList<>(v); - for (Iterator it = versions.iterator(); it.hasNext();) { - ComponentInfo cv = it.next(); - if (!resolvedMatch.test(cv.getVersion())) { - it.remove(); - } - } - return versions; - } - - private List doLoadComponents(String id, boolean filelist, boolean exact) { - String fid = exact ? id : findAbbreviatedId(id); - if (fid == null) { - return null; - } - List v = components.get(fid); - if (v == null) { - try { - Set infos = storage.loadComponentMetadata(fid); - if (infos == null || infos.isEmpty()) { - components.put(fid, NONE); - return null; - } - List versions = new ArrayList<>(infos); - for (Iterator it = versions.iterator(); it.hasNext();) { - ComponentInfo ci = it.next(); - // skip components that require capabilities that we do not have. - // Catalogs contain just "right" components, but in case someone will - // mess up the content, or directory-based mess catalog, the filter is handy. - if (capVerifier.validateRequirements(ci).hasErrors()) { - it.remove(); - } - } - Collections.sort(versions, ComponentInfo.versionComparator(installed.getManagementStorage())); - if (filelist) { - for (ComponentInfo ci : infos) { - storage.loadComponentFiles(ci); - } - components.put(fid, versions); - } - v = versions; - } catch (NoSuchFileException ex) { - return null; - } catch (IOException ex) { - throw env.failure("REGISTRY_ReadingComponentMetadata", ex, id, ex.getLocalizedMessage(), fid); - } - } - if (v == NONE) { - return null; - } - return v; - } - - @Override - public ComponentInfo findComponentMatch(String id, Version.Match vmatch, boolean localOnly, boolean exact) { - ComponentInfo ci = installed.loadSingleComponent(id, false); - if (ci != null) { - if (vmatch != null && vmatch.test(ci.getVersion())) { - return ci; - } - } - if (localOnly) { - return null; - } - return findComponentMatch(id, vmatch, exact); - } - - @Override - public Set findDependencies(ComponentInfo start, boolean closure, Boolean inst, Set result) { - return findDependencies(start, closure, inst, result, this::findComponentMatch); - } - - public interface ComponentQuery { - ComponentInfo findComponent(String id, Version.Match vmatch, boolean localOnly, boolean exact); - } - - public static Set findDependencies(ComponentInfo start, boolean closure, Boolean inst, Set result, ComponentQuery q) { - Set missing = new HashSet<>(); - Set known = new HashSet<>(); - Deque buffer = new ArrayDeque<>(); - buffer.add(start); - boolean localOnly = Boolean.TRUE.equals(inst); - while (!buffer.isEmpty()) { - ComponentInfo c = buffer.poll(); - Version.Match vm = c.getVersion().match(Version.Match.Type.COMPATIBLE); - for (String d : c.getDependencies()) { - if (!known.add(d)) { - continue; - } - ComponentInfo res = q.findComponent(d, vm, localOnly, true); - if (res == null) { - missing.add(d); - } else { - if (closure) { - buffer.add(res); - } - if (inst == null || (inst == res.isInstalled())) { - result.add(res); - } - } - } - } - return missing.isEmpty() ? null : missing; - } - - @Override - public DownloadInterceptor getDownloadInterceptor() { - return downloadInterceptor; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentInfo.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentInfo.java deleted file mode 100644 index 7bb1de53bce3..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentInfo.java +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; - -/** - * Information about an installable Component. - */ -public final class ComponentInfo { - /** - * Component ID. - */ - private final String id; - - /** - * Version of the component. - */ - private final String versionString; - - /** - * Parsed version of the Component. - */ - private final Version version; - - /** - * Human-readable name of the component. - */ - private final String name; - - /** - * During (un)installation only: the path for the .component info file. - */ - private String infoPath; - - /** - * Versioned license file path. - */ - private String licensePath; - - /** - * License type. - */ - private String licenseType; - - /** - * Assertions on graalVM installation. - */ - private final Map requiredGraalValues = new HashMap<>(); - - private final List paths = new ArrayList<>(); - - private final Set workingDirectories = new LinkedHashSet<>(); - - private final Map providedValues = new HashMap<>(); - - private URL remoteURL; - - private byte[] shaDigest; - - private String postinstMessage; - - private boolean nativeComponent; - - private String tag = ""; - - /** - * Component direct dependencies. Contains component canonical IDs. - */ - private Set dependencies = Collections.emptySet(); - - /** - * Origin of the component. - */ - private String origin; - - /** - * The distribution type. - */ - private DistributionType distributionType = DistributionType.OPTIONAL; - - /** - * Component priority. - */ - private int priority; - - /** - * Implicitly accepted license. - */ - private boolean implicitlyAccepted = false; - - private StabilityLevel stability = StabilityLevel.Undefined; - - public ComponentInfo(String id, String name, String versionString, String tag) { - this.id = id; - this.versionString = versionString; - this.name = name; - this.version = Version.fromString(versionString); - this.tag = tag; - } - - public ComponentInfo(String id, String name, String versionString) { - this(id, name, versionString, ""); // NOI18N - } - - public ComponentInfo(String id, String name, Version v) { - this.id = id; - this.versionString = v == null ? null : v.originalString(); - this.name = name; - this.version = v == null ? Version.NO_VERSION : v; - } - - public String getId() { - return id; - } - - public String getVersionString() { - return versionString; - } - - public String getName() { - return name; - } - - public DistributionType getDistributionType() { - return distributionType; - } - - public void setDistributionType(DistributionType distributionType) { - this.distributionType = distributionType; - } - - public Map getRequiredGraalValues() { - return Collections.unmodifiableMap(requiredGraalValues); - } - - public void addRequiredValues(Map vals) { - String os = vals.get(CommonConstants.CAP_OS_NAME); - String arch = vals.get(CommonConstants.CAP_OS_ARCH); - if (os != null) { - String nos = SystemUtils.normalizeOSName(os, arch); - if (!nos.equals(os)) { - vals.put(CommonConstants.CAP_OS_NAME, nos); - } - } - if (arch != null) { - String narch = SystemUtils.normalizeArchitecture(os, arch); - if (!narch.equals(os)) { - vals.put(CommonConstants.CAP_OS_ARCH, narch); - } - } - requiredGraalValues.putAll(vals); - } - - public void addRequiredValue(String s, String val) { - if (val == null) { - requiredGraalValues.remove(s); - } else { - String v = val; - switch (s) { - case CommonConstants.CAP_OS_ARCH: - v = SystemUtils.normalizeArchitecture(null, val); - break; - case CommonConstants.CAP_OS_NAME: - v = SystemUtils.normalizeOSName(val, null); - break; - default: - break; - } - requiredGraalValues.put(s, v); - } - } - - public void addPaths(List filePaths) { - paths.addAll(filePaths); - } - - public void setPaths(List filePaths) { - paths.clear(); - addPaths(filePaths); - } - - public List getPaths() { - return Collections.unmodifiableList(paths); - } - - public String getInfoPath() { - return infoPath; - } - - public void setInfoPath(String infoPath) { - this.infoPath = infoPath; - } - - public String getLicensePath() { - return licensePath; - } - - public void setLicensePath(String licensePath) { - this.licensePath = licensePath; - } - - public URL getRemoteURL() { - return remoteURL; - } - - public void setRemoteURL(URL remoteURL) { - this.remoteURL = remoteURL; - } - - public byte[] getShaDigest() { - return shaDigest; - } - - public void setShaDigest(byte[] shaDigest) { - this.shaDigest = shaDigest; - } - - public Set getWorkingDirectories() { - return workingDirectories; - } - - public void addWorkingDirectories(Collection dirs) { - workingDirectories.addAll(dirs); - } - - public String getPostinstMessage() { - return postinstMessage; - } - - public void setPostinstMessage(String postinstMessage) { - this.postinstMessage = postinstMessage; - } - - public String getLicenseType() { - return licenseType; - } - - public void setLicenseType(String licenseType) { - this.licenseType = licenseType; - } - - public boolean isImplicitlyAccepted() { - return implicitlyAccepted; - } - - public void setImplicitlyAccepted(boolean implicitlyAccepted) { - this.implicitlyAccepted = implicitlyAccepted; - } - - @Override - public int hashCode() { - int hash = 5; - hash = 37 * hash + Objects.hashCode(this.id); - hash = 37 * hash + Objects.hashCode(this.version); - hash = 37 * hash + Objects.hashCode(this.tag); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ComponentInfo other = (ComponentInfo) obj; - if (!Objects.equals(this.id, other.id)) { - return false; - } - if (!Objects.equals(this.version, other.version)) { - return false; - } - if (!Objects.equals(this.tag, other.tag)) { - return false; - } - return true; - } - - public Version getVersion() { - return version; - } - - private static Comparator editionComparator(String myEdition) { - return new Comparator<>() { - @Override - public int compare(ComponentInfo o1, ComponentInfo o2) { - if (o1 == null) { - if (o2 == null) { - return 0; - } else { - return -1; - } - } else if (o2 == null) { - return 1; - } - String ed1 = o1.getRequiredGraalValues().get(CommonConstants.CAP_CATALOG_EDITION); - String ed2 = o2.getRequiredGraalValues().get(CommonConstants.CAP_CATALOG_EDITION); - - boolean m1 = Objects.equals(ed1, myEdition); - boolean m2 = Objects.equals(ed2, myEdition); - - // one of the components exactly matches my edition: - if (m1) { - return m2 ? 0 : -1; - } else if (m2) { - return 1; - } - if (ed1 == null) { - ed1 = ""; - } - if (ed2 == null) { - ed2 = ""; - } - return ed1.compareToIgnoreCase(ed2); - } - }; - } - - private static final Comparator COMPARATOR_VERSIONS = new Comparator<>() { - @Override - public int compare(ComponentInfo o1, ComponentInfo o2) { - if (o1 == null) { - if (o2 == null) { - return 0; - } else { - return -1; - } - } else if (o2 == null) { - return 1; - } - - int n = o1.getVersion().compareTo(o2.getVersion()); - if (n == 0) { - return o2.getPriority() - o1.getPriority(); - } else { - return n; - } - } - }; - - @Override - public String toString() { - return getId() + "[" + getVersion().toString() + - (tag.isEmpty() ? "" : "/" + tag) + "]"; // NOI18N - } - - public static Comparator versionComparator() { - return COMPARATOR_VERSIONS; - } - - public static Comparator reverseVersionComparator(ComponentStorage target) { - String myEdition = target.loadGraalVersionInfo().get(CommonConstants.CAP_GRAALVM_VERSION); - return versionComparator().reversed().thenComparing(editionComparator(myEdition)); - } - - public static Comparator versionComparator(ComponentStorage target) { - String myEdition = target.loadGraalVersionInfo().get(CommonConstants.CAP_GRAALVM_VERSION); - return versionComparator().thenComparing(editionComparator(myEdition)); - } - - public String getOrigin() { - return origin; - } - - public void setOrigin(String origin) { - this.origin = origin; - } - - public boolean isNativeComponent() { - return nativeComponent; - } - - public void setNativeComponent(boolean nativeComponent) { - this.nativeComponent = nativeComponent; - } - - public void provideValue(String k, T v) { - providedValues.put(k, v); - } - - public T getProvidedValue(String k, Class type) { - Object o = providedValues.get(k); - if (!type.isInstance(o)) { - if (type != String.class || o == null) { - return null; - } - o = o.toString(); - } - @SuppressWarnings("unchecked") - T ret = (T) o; - return ret; - } - - public Map getProvidedValues() { - return Collections.unmodifiableMap(providedValues); - } - - public void addProvidedValues(Map vals) { - for (String s : vals.keySet()) { - provideValue(s, vals.get(s)); - } - } - - public void setDependencies(Set deps) { - this.dependencies = deps; - } - - public Set getDependencies() { - return Collections.unmodifiableSet(dependencies); - } - - /** - * @return True, if the Component is already installed. - */ - public boolean isInstalled() { - return infoPath != null; - } - - public String getTag() { - return tag; - } - - /** - * Sets the component tag. WARNING: do not use this after Component has been constructed; the - * call will change the hashCode + equals ! - * - * @param tag component tag/serial - */ - public void setTag(String tag) { - this.tag = tag; - } - - public int getPriority() { - return priority; - } - - public void setPriority(int priority) { - this.priority = priority; - } - - public StabilityLevel getStability() { - return stability; - } - - public void setStability(StabilityLevel stab) { - if (stab == null) { - this.stability = StabilityLevel.Undefined; - } else { - this.stability = stab; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentRegistry.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentRegistry.java deleted file mode 100644 index 795fbe77297b..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentRegistry.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.IOException; -import java.nio.file.NoSuchFileException; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.Objects; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; - -/** - * Models catalog of installed components. Works closely with {@link ComponentStorage} which handles - * serialization. - */ -public final class ComponentRegistry implements ComponentCollection { - private final ManagementStorage storage; - private final Feedback env; - - /** - * All components have been loaded. - */ - private boolean allLoaded; - - /** - * Indexes files path -> component(s). - */ - private Map> fileIndex; - - /** - * For each component ID, a list of components, in their ascending Version order. - */ - private Map components = new HashMap<>(); - private Map graalAttributes; - private Map> replacedFiles; - private Set componentDirectories; - - /** - * True, if replaced files have been changed. - */ - private boolean replaceFilesChanged; - - /** - * Allows update to a newer distribution, not just patches. This will cause components from - * newer GraalVM distributions to be accepted, even though it means a reinstall. Normally just - * minor patches are accepted so the current component can be replaced. - */ - private boolean allowDistUpdate; - - public ComponentRegistry(Feedback env, ManagementStorage storage) { - this.storage = storage; - this.env = env; - } - - public boolean compatibleVersion(Version v) { - Version gv = getGraalVersion(); - if (allowDistUpdate) { - return gv.updatable().equals(v.updatable()); - } else { - return gv.onlyVersion().equals(v.installVersion()); - } - } - - /** - * @return True, if components from newer distributions are allowed. - */ - @Override - public boolean isAllowDistUpdate() { - return allowDistUpdate; - } - - /** - * Enables components from newer distributions. - * - * @param allowDistUpdate - */ - @Override - public void setAllowDistUpdate(boolean allowDistUpdate) { - this.allowDistUpdate = allowDistUpdate; - } - - @Override - public ComponentInfo findComponentMatch(String idspec, Version.Match vm, boolean exact) { - Version.Match[] vmatch = new Version.Match[1]; - String id = Version.idAndVersion(idspec, vmatch); - if (!allLoaded) { - return loadSingleComponent(id, false, false, exact); - } - ComponentInfo ci = components.get(id); - if (ci != null) { - return ci; - } - String fullId = exact ? id : findAbbreviatedId(id); - return fullId == null ? null : components.get(fullId); - } - - private String findAbbreviatedId(String id) { - String candidate = null; - String lcid = id.toLowerCase(Locale.ENGLISH); - String end = "." + lcid; // NOI18N - Collection ids = getComponentIDs(); - String ambiguous = null; - for (String s : ids) { - String lcs = s.toLowerCase(Locale.ENGLISH); - if (lcs.equals(lcid)) { - return s; - } - if (lcs.endsWith(end)) { - if (candidate != null) { - ambiguous = s; - } else { - candidate = s; - } - } - } - if (ambiguous != null) { - throw env.failure("COMPONENT_AmbiguousIdFound", null, candidate, ambiguous); - } - return candidate; - } - - /** - * Regexp to extract specification version. Optional {@code "1."} in front, optional - * {@code ".micro_patchlevel"} suffix. - */ - private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("((?:1\\.)?[0-9]+)([._].*)?"); // NOI18N - - private String overrideEdition; - - public void setOverrideEdition(String overrideEdition) { - this.overrideEdition = overrideEdition; - } - - public Map getGraalCapabilities() { - if (graalAttributes != null) { - return graalAttributes; - } - Map m = new HashMap<>(storage.loadGraalVersionInfo()); - String v = m.get(CommonConstants.CAP_JAVA_VERSION); - if (v != null) { - Matcher rm = JAVA_VERSION_PATTERN.matcher(v); - if (rm.matches()) { - v = rm.group(1); - } - int mv = SystemUtils.interpretJavaMajorVersion(v); - if (mv < 1) { - m.remove(CommonConstants.CAP_JAVA_VERSION); - } else { - m.put(CommonConstants.CAP_JAVA_VERSION, "" + mv); // NOI18N - } - graalAttributes = m; - } - // On JDK11, amd64 architecture name changed to x86_64. - v = SystemUtils.normalizeArchitecture( - m.get(CommonConstants.CAP_OS_NAME), - m.get(CommonConstants.CAP_OS_ARCH)); - if (v != null) { - m.put(CommonConstants.CAP_OS_ARCH, v); - } - v = SystemUtils.normalizeOSName( - m.get(CommonConstants.CAP_OS_NAME), - m.get(CommonConstants.CAP_OS_ARCH)); - if (v != null) { - m.put(CommonConstants.CAP_OS_NAME, v); - } - if (overrideEdition != null) { - graalAttributes.put(CommonConstants.CAP_EDITION, overrideEdition); - } - return graalAttributes; - } - - @Override - public Collection getComponentIDs() { - if (!allLoaded) { - try { - return storage.listComponentIDs(); - } catch (IOException ex) { - throw env.failure("REGISTRY_ReadingComponentList", ex, ex.getLocalizedMessage()); - } - } else { - return Collections.unmodifiableCollection(components.keySet()); - } - } - - public void removeComponent(ComponentInfo info) throws IOException { - replaceFilesChanged = false; - buildFileIndex(); - String id = info.getId(); - for (String p : info.getPaths()) { - Collection compIds = fileIndex.get(p); - if (compIds != null && compIds.remove(id)) { - replaceFilesChanged = true; - if (compIds.isEmpty()) { - fileIndex.remove(p); - componentDirectories.remove(p); - } - } - } - if (allLoaded) { - components.remove(id); - } - storage.deleteComponent(id); - updateReplacedFiles(); - } - - /** - * Adds a Component to the registry. Will not save info, but will merge component information - * with the rest. - * - * @param info - */ - public void addComponent(ComponentInfo info) throws IOException { - replaceFilesChanged = false; - // includes load all components - buildFileIndex(); - String id = info.getId(); - for (String p : info.getPaths()) { - Collection compIds = fileIndex.computeIfAbsent(p, (k) -> new HashSet<>()); - replaceFilesChanged |= !compIds.isEmpty(); - compIds.add(id); - if (p.endsWith("/")) { - componentDirectories.add(p); - } - } - if (allLoaded) { - addComponentToCache(info); - } - storage.saveComponent(info); - updateReplacedFiles(); - } - - private void addComponentToCache(ComponentInfo info) { - String id = info.getId(); - ComponentInfo old = components.put(id, info); - if (old != null) { - throw new IllegalStateException("Replacing existing component"); - } - } - - private void computeReplacedFiles() { - Map> shared = new LinkedHashMap<>(); - List keys = new ArrayList<>(fileIndex.keySet()); - Collections.sort(keys); - for (String p : keys) { - Collection compIds = fileIndex.get(p); - if (compIds != null && compIds.size() > 1) { - shared.put(p, compIds); - } - } - this.replacedFiles = shared; - } - - private void updateReplacedFiles() throws IOException { - if (!replaceFilesChanged) { - return; - } - computeReplacedFiles(); - storage.updateReplacedFiles(replacedFiles); - } - - public List getPreservedFiles(ComponentInfo info) { - buildFileIndex(); - - List result = new ArrayList<>(); - for (String p : info.getPaths()) { - Collection compIds = fileIndex.get(p); - if (compIds != null && compIds.size() > 1) { - result.add(p); - } - } - // we should preserve this one - result.add(CommonConstants.PATH_COMPONENT_STORAGE); - return result; - } - - public List getOwners(String p) { - buildFileIndex(); - Collection compIds = fileIndex.get(p); - if (compIds == null) { - return Collections.emptyList(); - } - List ret = new ArrayList<>(compIds); - Collections.sort(ret); - return ret; - } - - public boolean isReplacedFilesChanged() { - return replaceFilesChanged; - } - - private void loadAllComponents() { - if (allLoaded) { - return; - } - String currentId = null; - try { - Collection ids = storage.listComponentIDs(); - components = new HashMap<>(); - for (String id : ids) { - loadSingleComponent(id, true); - } - allLoaded = true; - } catch (IOException ex) { - throw env.failure("REGISTRY_ReadingComponentMetadata", ex, currentId, ex.getLocalizedMessage()); - } - } - - public ComponentInfo loadSingleComponent(String id, boolean filelist) { - return loadSingleComponent(id, filelist, false, false); - } - - @Override - public Collection loadComponents(String id, Version.Match selector, boolean filelist) { - ComponentInfo ci = loadSingleComponent(id, filelist); - return ci == null ? null : Collections.singletonList(ci); - } - - ComponentInfo loadSingleComponent(String id, boolean filelist, boolean notFoundFailure, boolean exact) { - String fid = exact ? id : findAbbreviatedId(id); - if (fid == null) { - if (notFoundFailure) { - throw env.failure("REMOTE_UnknownComponentId", null, id); - } else { - return null; - } - } - ComponentInfo info = components.get(fid); - if (info != null) { - return info; - } - String cid = id; - try { - Collection infos = storage.loadComponentMetadata(fid); - if (infos == null || infos.isEmpty()) { - if (notFoundFailure) { - throw env.failure("REMOTE_UnknownComponentId", null, id); - } - return null; - } - if (infos.size() != 1) { - throw new IllegalArgumentException("Wrong storage"); - } - info = infos.iterator().next(); - cid = info.getId(); // may change if id was an abbreviation - if (filelist) { - storage.loadComponentFiles(info); - components.put(cid, info); - } - } catch (NoSuchFileException ex) { - return null; - } catch (IOException ex) { - throw env.failure("REGISTRY_ReadingComponentMetadata", ex, id, ex.getLocalizedMessage(), fid); - } - return info; - } - - private void buildFileIndex() { - // first load all the components - if (fileIndex != null) { - return; - } - loadAllComponents(); - componentDirectories = new HashSet<>(); - fileIndex = new HashMap<>(); - for (ComponentInfo nfo : components.values()) { - for (String path : nfo.getPaths()) { - if (path.endsWith("/")) { - componentDirectories.add(path); - } - fileIndex.computeIfAbsent(path, (k) -> new ArrayList<>()).add(nfo.getId()); - } - } - computeReplacedFiles(); - } - - public List getReplacedFiles(String path) { - buildFileIndex(); - Collection l = replacedFiles.get(path); - if (l == null) { - return Collections.emptyList(); - } - List ret = new ArrayList<>(l); - Collections.sort(ret); - return ret; - } - - /** - * Computes a set of directories created by components. - * - * @return set of directories created by components - */ - public Set getComponentDirectories() { - buildFileIndex(); - return componentDirectories; - } - - public String localizeCapabilityName(String s) { - String capName = "INSTALL_Capability_" + s.toLowerCase(); - String dispCapName; - try { - dispCapName = env.l10n(capName); - } catch (MissingResourceException ex) { - // some additional header - dispCapName = s; - } - return dispCapName; - } - - @Override - public String shortenComponentId(ComponentInfo info) { - String id = info.getId(); - if (id.startsWith(CommonConstants.GRAALVM_CORE_PREFIX)) { - int l = CommonConstants.GRAALVM_CORE_PREFIX.length(); - if (id.length() == l) { - return CommonConstants.GRAALVM_CORE_SHORT_ID; - } - if (id.charAt(l) != '.' && id.length() > l + 1) { - return id; - } - String shortId = id.substring(l + 1); - try { - ComponentInfo reg = findComponent(shortId); - if (reg == null || reg.getId().equals(id)) { - return shortId; - } - } catch (FailedOperationException ex) { - // ambiguous, ignore - } - } - return id; - } - - public Date isLicenseAccepted(ComponentInfo info, String id) { - return storage.licenseAccepted(info, id); - } - - public void acceptLicense(ComponentInfo info, String id, String text) { - acceptLicense(info, id, text, null); - } - - public void acceptLicense(ComponentInfo info, String id, String text, Date d) { - try { - storage.recordLicenseAccepted(info, id, text, d); - } catch (IOException ex) { - env.error("ERROR_RecordLicenseAccepted", ex, ex.getLocalizedMessage()); - } - } - - private Version graalVer; - - public Version getGraalVersion() { - if (graalVer == null) { - graalVer = Version.fromString(getGraalCapabilities().get(CommonConstants.CAP_GRAALVM_VERSION)); - } - return graalVer; - } - - public Map> getAcceptedLicenses() { - return storage.findAcceptedLicenses(); - } - - public String licenseText(String licId) { - return storage.licenseText(licId); - } - - public boolean isMacOsX() { - return storage.loadGraalVersionInfo().get("os_name").toLowerCase().contains("macos"); - } - - public void verifyAdministratorAccess() throws IOException { - storage.saveComponent(null); - } - - /** - * Finds components which depend on the supplied one. Optionally searches recursively, so it - * finds the dependency closure. - * - * @param recursive create closure of dependent components. - * @param startFrom Component whose dependents should be returned. - * @return Dependent components or closure thereof, depending on parameters - */ - public Set findDependentComponents(ComponentInfo startFrom, boolean recursive) { - if (startFrom == null) { - return Collections.emptySet(); - } - Deque toSearch = new ArrayDeque<>(); - toSearch.add(startFrom.getId()); - Set result = new HashSet<>(); - - while (!toSearch.isEmpty()) { - String id = toSearch.poll(); - for (String cid : getComponentIDs()) { - ComponentInfo ci = loadSingleComponent(cid, false, false, true); - if (ci.getDependencies().contains(id)) { - result.add(ci); - if (recursive) { - toSearch.add(ci.getId()); - } - } - } - } - return result; - } - - public String getJavaVersion() { - return getGraalCapabilities().get(CommonConstants.CAP_JAVA_VERSION); - } - - public ManagementStorage getManagementStorage() { - return storage; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 97 * hash + Objects.hashCode(this.storage); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ComponentRegistry other = (ComponentRegistry) obj; - if (!Objects.equals(this.storage, other.storage)) { - return false; - } - return true; - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentStorage.java deleted file mode 100644 index 545592035052..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ComponentStorage.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.IOException; -import java.util.Map; -import java.util.Set; - -/** - * Serialization of {@link ComponentRegistry}. - */ -public interface ComponentStorage { - /** - * Loads list of components. - * - * @return set of component IDs - * @throws IOException when I/O fails - */ - Set listComponentIDs() throws IOException; - - /** - * Loads component files into its metadata. - * - * @param ci the component metadata - * @return the modified ComponentInfo - * @throws IOException on I/O errors - */ - ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException; - - /** - * Deserializes Component's metadata. - * - * @param id component ID - * @return matching ComponentInfo instances - * @throws IOException on I/O errors - */ - Set loadComponentMetadata(String id) throws IOException; - - Map loadGraalVersionInfo(); - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/DistributionType.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/DistributionType.java deleted file mode 100644 index 890ba267e814..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/DistributionType.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -/** - * Distribution type for a component. Distribution type determines the operations that can be - * applied to it. - * - * @author sdedic - */ -public enum DistributionType { - /** - * Component is bundled, was installed with the GraalVM package. The component is NOT removable. - */ - BUNDLED, - - /** - * Component was installed as an add-on. It can be removed by the user. This is the default - * value when no distribution type is specified. - */ - OPTIONAL -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/GraalEdition.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/GraalEdition.java deleted file mode 100644 index 0976f4ff3488..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/GraalEdition.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; - -/** - * Represents GraalVM edition. Each installation has an edition. - * - * @author sdedic - */ -public class GraalEdition { - private final String id; - private final String displayName; - private List softwareSources = new ArrayList<>(); - - /** - * Components from that specific edition. - */ - private SoftwareChannel catalogProvider; - - public GraalEdition(String id, String displayName) { - this.id = id; - this.displayName = displayName; - } - - public SoftwareChannel getCatalogProvider() { - return catalogProvider; - } - - public String getId() { - return id; - } - - public String getDisplayName() { - return displayName; - } - - public void setSoftwareSources(List sources) { - this.softwareSources = sources; - } - - public void setCatalogProvider(SoftwareChannel catalogProvider) { - this.catalogProvider = catalogProvider; - } - - public List getSoftwareSources() { - return softwareSources; - } - - @Override - public int hashCode() { - int hash = 3; - hash = 53 * hash + Objects.hashCode(this.id); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final GraalEdition other = (GraalEdition) obj; - if (!Objects.equals(this.id, other.id)) { - return false; - } - return true; - } - - @Override - public String toString() { - if (id.equals(displayName)) { - return "Graal " + id; - } else { - return "Graal " + id + "(" + displayName + ")"; - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ManagementStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ManagementStorage.java deleted file mode 100644 index f53a8a07493f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/ManagementStorage.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.io.IOException; -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -/** - * - * @author sdedic - */ -public interface ManagementStorage extends ComponentStorage { - /** - * Deletes component's files. - * - * @param id component ID - * @throws IOException on load error - */ - void deleteComponent(String id) throws IOException; - - Map> readReplacedFiles() throws IOException; - - void saveComponent(ComponentInfo info) throws IOException; - - void updateReplacedFiles(Map> replacedFiles) throws IOException; - - /** - * Checks that the license was already accepted. - * - * @param info component for which the license should be checked - * @param licenseID the ID to check - * @return time when the license was accepted - */ - Date licenseAccepted(ComponentInfo info, String licenseID); - - /** - * Records that the license has been accepted. If id is {@code} null, then all license records - * are erased. - * - * @param info the component for which the license is accepted - * @param licenseID the ID to accept or {@code null} - * @param licenseText text of the license, will be recoded. - */ - void recordLicenseAccepted(ComponentInfo info, String licenseID, String licenseText, Date d) throws IOException; - - /** - * Returns accepted licenses. The map is keyed by component ID, values are collections of - * acceped licenses. - * - * @return accepted licenses - */ - Map> findAcceptedLicenses(); - - String licenseText(String licID); -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/RemoteInfoProcessor.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/RemoteInfoProcessor.java deleted file mode 100644 index 10c158f91cb5..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/RemoteInfoProcessor.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -/** - * Interface to decorate ComponentInfo for remote installables. - * - * @author sdedic - */ -public interface RemoteInfoProcessor { - ComponentInfo decorateComponent(ComponentInfo info); - - RemoteInfoProcessor NONE = new RemoteInfoProcessor() { - @Override - public ComponentInfo decorateComponent(ComponentInfo info) { - return info; - } - }; -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/StabilityLevel.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/StabilityLevel.java deleted file mode 100644 index 9395f2284dfa..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/StabilityLevel.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.util.Locale; -import org.graalvm.component.installer.Feedback; - -/** - * Values for the stability level of a component. - * - * @author sdedic - */ -public enum StabilityLevel { - Undefined("undefined"), - Supported("supported"), - EarlyAdopter("earlyadopter"), - Experimental("experimental"), - Experimental_Earlyadopter("experimental-earlyadopter"); - - private final String val; - - StabilityLevel(String aVal) { - val = aVal; - } - - public String displayName(Feedback fb) { - return fb.withBundle(StabilityLevel.class).l10n("ComponentStabilityLevel_" + name().toLowerCase()); - } - - @Override - public String toString() { - if (this == Undefined) { - return ""; - } else { - return val; - } - } - - public static StabilityLevel valueOfMixedCase(String mcs) { - if (mcs.isEmpty()) { - return Undefined; - } - String s = mcs.replaceAll("[^\\p{Alnum}]", "_").toLowerCase(Locale.ENGLISH); - for (StabilityLevel l : StabilityLevel.values()) { - if (l.name().toLowerCase(Locale.ENGLISH).equalsIgnoreCase(s)) { - return l; - } - } - return Undefined; - } - - public static StabilityLevel fromName(String name) { - for (StabilityLevel level : values()) { - if (level.val.equals(name)) { - return level; - } - } - return StabilityLevel.Undefined; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Verifier.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Verifier.java deleted file mode 100644 index 41eec5bac658..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/model/Verifier.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.model; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.graalvm.component.installer.BundleConstants; -import static org.graalvm.component.installer.BundleConstants.GRAALVM_CAPABILITY; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.ComponentInstaller; -import org.graalvm.component.installer.DependencyException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SuppressFBWarnings; -import org.graalvm.component.installer.Version; - -public class Verifier { - private final Feedback feedback; - private final ComponentRegistry localRegistry; - private final ComponentCollection catalog; - private boolean silent; - private boolean replaceComponents; - private boolean ignoreRequirements; - private boolean collectErrors; - private boolean ignoreExisting; - private boolean collectVersion; - - private Version.Match versionMatch; - private Version minVersion; - private List errors = new ArrayList<>(); - - public Verifier(Feedback feedback, ComponentRegistry registry, ComponentCollection catalog) { - this.feedback = feedback.withBundle(ComponentInstaller.class); - this.localRegistry = registry; - this.catalog = catalog; - } - - public boolean isCollectVersion() { - return collectVersion; - } - - public Verifier collectVersion(boolean collect) { - this.collectVersion = collect; - return this; - } - - public Version getMinVersion() { - return minVersion; - } - - public boolean isSilent() { - return silent; - } - - public void setSilent(boolean silent) { - this.silent = silent; - } - - public Version.Match getVersionMatch() { - return versionMatch; - } - - public Verifier setVersionMatch(Version.Match versionMatch) { - this.versionMatch = versionMatch; - return this; - } - - public boolean hasErrors() { - return !errors.isEmpty(); - } - - public boolean isCollectErrors() { - return collectErrors; - } - - public void setCollectErrors(boolean collectErrors) { - this.collectErrors = collectErrors; - } - - public boolean isIgnoreExisting() { - return ignoreExisting; - } - - public Verifier ignoreExisting(boolean ignore) { - this.ignoreExisting = ignore; - return this; - } - - public boolean isReplaceComponents() { - return replaceComponents; - } - - public Verifier replaceComponents(boolean value) { - this.replaceComponents = value; - return this; - } - - public boolean isIgnoreRequirements() { - return ignoreRequirements; - } - - public Verifier ignoreRequirements(boolean value) { - this.ignoreRequirements = value; - return this; - } - - public Verifier collect(boolean value) { - this.collectErrors = value; - return this; - } - - private void addOrThrow(DependencyException ex) { - if (collectErrors) { - errors.add(ex); - } else { - throw ex; - } - } - - public void printRequirements(ComponentInfo info) { - if (isSilent()) { - return; - } - Map requiredCaps = info.getRequiredGraalValues(); - Map graalCaps = localRegistry.getGraalCapabilities(); - - if (feedback.verboseOutput("VERIFY_VerboseCheckRequirements", catalog.shortenComponentId(info), info.getName(), info.getVersionString())) { - List keys = new ArrayList<>(requiredCaps.keySet()); - Collections.sort(keys); - String none = feedback.l10n("VERIFY_VerboseCapabilityNone"); - for (String s : keys) { - String v = graalCaps.get(s); - feedback.verboseOutput("VERIFY_VerboseCapability", localRegistry.localizeCapabilityName(s), requiredCaps.get(s), v == null ? none : v); - } - } - } - - public List getErrors() { - return errors; - } - - public boolean shouldInstall(ComponentInfo componentInfo) { - if (replaceComponents) { - return true; - } - ComponentInfo existing = localRegistry.findComponent(componentInfo.getId()); - return existing == null || - existing.getVersion().compareTo(componentInfo.getVersion()) < 0; - } - - @SuppressWarnings("StringEquality") - @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "intentional comparison of strings using ==") - public Verifier validateRequirements(ComponentInfo componentInfo) { - errors.clear(); - // check the component is not in the registry - ComponentInfo existing = localRegistry.findComponent(componentInfo.getId()); - if (existing != null) { - if (existing.getVersion().compareTo(componentInfo.getVersion()) >= 0) { - if (!ignoreExisting && !replaceComponents) { - addOrThrow(new DependencyException.Conflict( - existing.getId(), componentInfo.getVersionString(), existing.getVersionString(), - feedback.l10n("VERIFY_ComponentExists", - existing.getName(), existing, existing.getVersionString()))); - } - } - } - if (ignoreRequirements) { - return this; - } - Map requiredCaps = componentInfo.getRequiredGraalValues(); - Map graalCaps = localRegistry.getGraalCapabilities(); - boolean verbose = feedback.verboseOutput(null); - if (!isSilent() && verbose) { - feedback.verboseOutput("VERIFY_VerboseCheckRequirements", catalog.shortenComponentId(componentInfo), componentInfo.getName(), componentInfo.getVersionString()); - List keys = new ArrayList<>(requiredCaps.keySet()); - Collections.sort(keys); - String none = feedback.l10n("VERIFY_VerboseCapabilityNone"); - for (String s : keys) { - String v = graalCaps.get(s); - feedback.verboseOutput("VERIFY_VerboseCapability", localRegistry.localizeCapabilityName(s), requiredCaps.get(s), v == null ? none : v); - } - } - - for (String s : requiredCaps.keySet()) { - String reqVal = requiredCaps.get(s); - String graalVal = graalCaps.get(s); - boolean matches; - if (BundleConstants.GRAAL_VERSION.equals(s)) { - if (versionMatch != null) { - Version cv = Version.fromString( - reqVal.toLowerCase()); - matches = versionMatch.test(cv); - } else { - Version rv = Version.fromString(reqVal); - Version gv = Version.fromString(graalVal); - matches = rv.installVersion().equals(gv.installVersion()); - } - if (!matches) { - Version rq = Version.fromString(reqVal); - Version gv = localRegistry.getGraalVersion(); - int n = gv.compareTo(rq); - if (n > 0) { - if (!gv.installVersion().equals(rq.installVersion())) { - addOrThrow(new DependencyException.Mismatch( - GRAALVM_CAPABILITY, - s, reqVal, graalVal, - feedback.l10n("VERIFY_ObsoleteGraalVM", - componentInfo.getName(), reqVal, gv.displayString()))); - } - } else if (collectVersion) { - minVersion = rq; - } else { - addOrThrow(new DependencyException.Mismatch( - GRAALVM_CAPABILITY, - s, reqVal, graalVal, - feedback.l10n("VERIFY_UpdateGraalVM", - componentInfo.getName(), reqVal, gv.displayString()))); - } - } - continue; - } else { - matches = matches(reqVal, graalVal); - } - if (!matches) { - String val = graalVal != null ? graalVal : feedback.l10n("VERIFY_CapabilityMissing"); - addOrThrow(new DependencyException.Mismatch( - componentInfo.getId(), - s, reqVal, graalVal, - feedback.l10n("VERIFY_Dependency_Failed", - componentInfo.getName(), localRegistry.localizeCapabilityName(s), reqVal, val))); - } - } - return this; - } - - private static boolean matches(String reqVal, String graalVal) { - return !((reqVal != graalVal) && (reqVal == null || graalVal == null || (reqVal.replace('-', '_').compareToIgnoreCase(graalVal.replace('-', '_')) != 0))); - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/Bundle.properties deleted file mode 100644 index 1e3eec2383fe..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/Bundle.properties +++ /dev/null @@ -1,5 +0,0 @@ -# {0} path to the file or directory -# {1} message -ERR_CannotDeletePath=Could not delete path {0}: {1} -MSG_DeleteObsoleteFiles=Deleting obsolete files... -MSG_CopyNewFiles=Copying in new files... \ No newline at end of file diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/DefaultFileOperations.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/DefaultFileOperations.java deleted file mode 100644 index 4871f328434e..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/DefaultFileOperations.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.os; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermission; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.Set; -import java.util.concurrent.Callable; -import org.graalvm.component.installer.FileOperations; - -/** - * - * @author sdedic - */ -public class DefaultFileOperations extends FileOperations { - - private static final Set ALL_WRITE_PERMS = PosixFilePermissions.fromString("rwxrwxrwx"); // NOI18N - - @Override - protected boolean doWithPermissions(Path p, Callable action) throws IOException { - Set restoreDirPermissions = null; - Files.setPosixFilePermissions(p, ALL_WRITE_PERMS); - Path d = p.normalize().getParent(); - // set the parent directory's permissions, but do not - // alter permissions outside the to-be-deleted tree: - if (d == null) { - throw new IOException("Cannot determine parent of " + p); - } - if (d.startsWith(rootPath()) && !d.equals(rootPath())) { - restoreDirPermissions = Files.getPosixFilePermissions(d); - try { - Files.setPosixFilePermissions(d, ALL_WRITE_PERMS); - } catch (IOException ex) { - // mask out, but report failure - return false; - } - } - boolean ok = false; - try { - action.call(); - ok = true; - } catch (IOException ex) { - throw ex; - } catch (Exception ex) { - ok = false; - } finally { - if (restoreDirPermissions != null) { - try { - Files.setPosixFilePermissions(d, restoreDirPermissions); - } catch (IOException ex2) { - // do not obscure the result with this exception - feedback().error("FILE_ErrorRestoringPermissions", ex2, p, ex2.getLocalizedMessage()); - ok = false; - } - } - - } - return ok; - } - - @Override - public void setPermissions(Path target, Set perms) throws IOException { - Files.setPosixFilePermissions(target, perms); - } - - @Override - public boolean flush() { - return false; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsFileOperations.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsFileOperations.java deleted file mode 100644 index 8b31d600f733..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsFileOperations.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.os; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.nio.file.attribute.AclEntry; -import java.nio.file.attribute.AclEntryPermission; -import java.nio.file.attribute.AclEntryType; -import java.nio.file.attribute.AclFileAttributeView; -import java.nio.file.attribute.PosixFilePermission; -import java.nio.file.attribute.UserPrincipal; -import java.nio.file.attribute.UserPrincipalLookupService; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.NavigableSet; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.Callable; -import org.graalvm.component.installer.FileOperations; - -/** - * Windows-specific FileOperations, with delayed deletes and renames. {@link #setDelayDeletedList} - * and {@link #setCopyContents} must be used prior to working with files so the failed operations - * are recorded for the post-run batch processing. In SVM mode, these properties are unset, so any - * file operation failure will be reported immediately. - * - * @author sdedic - */ -public class WindowsFileOperations extends FileOperations { - /** - * File that contains list of delayed deletions. - */ - private Path delayDeletedList; - - /** - * File that contains move instructions. - */ - private Path copyContents; - - /** - * Paths which have been copied because of locked files. - */ - private Map copiedPaths = new HashMap<>(); - - /** - * Paths which should be deleted, but the operation must be delayed. - */ - private NavigableSet delayDeletedPaths = new TreeSet<>(); - - public void setDelayDeletedList(Path delayDeletedList) { - this.delayDeletedList = delayDeletedList; - } - - public void setCopyContents(Path copyContents) { - this.copyContents = copyContents; - } - - public Map getCopiedPaths() { - return copiedPaths; - } - - public Set getDelayDeletedPaths() { - return delayDeletedPaths; - } - - @Override - protected boolean doWithPermissions(Path p, Callable action) throws IOException { - AclFileAttributeView aclView = Files.getFileAttributeView(p, AclFileAttributeView.class); - UserPrincipalLookupService upls = p.getFileSystem().getUserPrincipalLookupService(); - String un = System.getProperty("user.name"); // NOI18N - UserPrincipal up; - List save; - - try { - up = upls.lookupPrincipalByName(un); - save = aclView.getAcl(); - - List temp = new ArrayList<>(save); - AclEntry en = AclEntry.newBuilder().setType(AclEntryType.ALLOW).setPrincipal(up).setPermissions(AclEntryPermission.DELETE).build(); - temp.add(en); - aclView.setAcl(temp); - } catch (IOException ex) { - // expected, bail out - return false; - } - - boolean ok = false; - try { - action.call(); - ok = true; - } catch (IOException ex) { - throw ex; - } catch (Exception ex) { - ok = false; - } finally { - try { - aclView.setAcl(save); - } catch (IOException ex) { - // do not obscure the result with this exception - feedback().error("FILE_ErrorRestoringPermissions", ex, p, ex.getLocalizedMessage()); - // expected, bail out - ok = false; - } - - } - return ok; - } - - @Override - public boolean flush() throws IOException { - boolean r = false; - if (copyContents != null) { - List lines = new ArrayList<>(copiedPaths.size()); - for (Map.Entry e : copiedPaths.entrySet()) { - Path orig = e.getKey(); - if (Files.exists(orig)) { - String s = orig.toAbsolutePath().toString() + "|" + e.getValue().toAbsolutePath().toString(); - lines.add(s); - // do not delete the directory's contents. - delayDeletedPaths.remove(orig); - } - } - if (!lines.isEmpty()) { - r = true; - } - Files.write(copyContents, lines, - StandardOpenOption.CREATE, - StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING); - } - if (delayDeletedList != null) { - List lines = new ArrayList<>(delayDeletedPaths.size()); - for (Path p : delayDeletedPaths) { - lines.add(p.toAbsolutePath().toString()); - } - if (!lines.isEmpty()) { - r = true; - } - Files.write(delayDeletedList, lines, - StandardOpenOption.CREATE, - StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING); - } - return r; - } - - @Override - protected void handleUndeletableFile(IOException ex, Path p) throws IOException { - if (delayDeletedList == null) { - super.handleUndeletableFile(ex, p); - return; - } - delayDeletedPaths.add(p); - feedback().output("FILE_CannotDeleteFileTryDelayed", p, ex.getLocalizedMessage()); - } - - @Override - protected Path handleUnmodifiableFile(IOException ex, Path p, InputStream content) throws IOException { - if (copyContents == null) { - return super.handleUnmodifiableFile(ex, p, content); - } - Path fn = p.getFileName(); - Path parentDir = p.getParent(); - assert parentDir != null; - assert fn != null; - Path pn = parentDir.getFileName(); - assert pn != null; - Path copy = parentDir.resolveSibling(pn.toString() + ".new"); - copiedPaths.put(parentDir, copy); - - feedback().output("FILE_CannotInstallFileTryDelayed", p, ex.getLocalizedMessage()); - - Files.createDirectories(copy); - Path target = copy.resolve(fn); - Files.copy(content, target, StandardCopyOption.REPLACE_EXISTING); - return target; - } - - /** - * Materializes the path. The input path is relative to the root; the path will be resolved - * against the root. Then, if copy-on-write was performed, the path will be redirected to a - * sibling directory. - * - * @param p the path to materialize - * - * @return the target path or {@code null} - */ - @Override - public Path materialize(Path p, boolean write) { - if (copyContents == null || delayDeletedList == null) { - return super.materialize(p, write); - } - Path parentDir = p.getParent(); - Path copy = copiedPaths.get(parentDir); - Path fn = p.getFileName(); - assert fn != null; - assert parentDir != null; - if (copy != null) { - Path r = copy.resolve(fn); - return r; - } - if (delayDeletedPaths.contains(p)) { - if (write) { - Path pn = parentDir.getFileName(); - assert pn != null; - copy = parentDir.resolveSibling(pn.toString() + ".new"); - copiedPaths.put(parentDir, copy); - return copy.resolve(fn); - } else { - // the file was deleted. - return null; - } - } - return p; - } - - @Override - public void setPermissions(Path target, Set perms) throws IOException { - // ignore permissions on Windows. - } - - @Override - protected void performDelete(Path p) throws IOException { - // check if something inside the subtree was scheduled for delay-delete. - // If so, then schedule also the parent: - Path next = delayDeletedPaths.ceiling(p); - if (next != null && next.startsWith(p)) { - feedback().output("FILE_CannotDeleteParentTryDelayed", p); - } else { - super.performDelete(p); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsJVMWrapper.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsJVMWrapper.java deleted file mode 100644 index 179dc16230f5..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/os/WindowsJVMWrapper.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.os; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileOperations; -import org.graalvm.component.installer.SystemUtils; - -/** - * - * @author sdedic - */ -public class WindowsJVMWrapper { - private final Feedback fb; - private final FileOperations fileOps; - private final Path installPath; - - private String mainClass; - private String jvmBinary; - private List args = Collections.emptyList(); - private List jvmArgs = Collections.emptyList(); - private String classpath = "."; // NOI18N - - public WindowsJVMWrapper(Feedback fb, FileOperations fops, Path installPath) { - this.fb = fb.withBundle(WindowsJVMWrapper.class); - this.fileOps = fops; - this.installPath = installPath; - } - - public WindowsJVMWrapper vm(String path, List vmArgs) { - jvmBinary = path; - jvmArgs = vmArgs; - return this; - } - - public WindowsJVMWrapper mainClass(String mc) { - this.mainClass = mc; - return this; - } - - public WindowsJVMWrapper classpath(String cp) { - this.classpath = cp; - return this; - } - - public WindowsJVMWrapper args(List a) { - this.args = a; - return this; - } - - public int execute() throws IOException { - assert mainClass != null; - assert jvmBinary != null; - - Path copyPath = Files.createTempFile("gu_copy_", ".lst"); // NOI18N - Path deletePath = Files.createTempFile("gu_delete", ".lst"); // NOI18N - copyPath.toFile().deleteOnExit(); - deletePath.toFile().deleteOnExit(); - - ProcessBuilder builder = new ProcessBuilder(); - Map env = builder.environment(); - env.put(CommonConstants.ENV_COPY_CONTENTS, copyPath.toAbsolutePath().toString()); - env.put(CommonConstants.ENV_DELETE_LIST, deletePath.toAbsolutePath().toString()); - - List all = new ArrayList<>(jvmArgs.size() + args.size() + 1); - all.add(jvmBinary); - if (classpath != null) { - all.add("-classpath"); // NOI18N - all.add(classpath); - } - all.addAll(jvmArgs); - all.add(mainClass); - all.addAll(args); - - Process proc = builder.command(all).inheritIO().start(); - - try { - proc.waitFor(); - } catch (InterruptedException ex) { - } - int exitValue = proc.exitValue(); - if (exitValue != CommonConstants.WINDOWS_RETCODE_DELAYED_OPERATION) { - return exitValue; - } - deleteRecursively(deletePath); - copyContents(copyPath); - return 0; - } - - void copyContents(Path listFile) throws IOException { - boolean first = true; - for (String desc : Files.readAllLines(listFile)) { - int i = desc.indexOf('|'); - if (i == -1) { - continue; - } - Path p = SystemUtils.fromUserString(desc.substring(0, i)); - Path q = SystemUtils.fromUserString(desc.substring(i + 1)); - if (first) { - fb.message("MSG_CopyNewFiles"); - first = false; - } - SystemUtils.copySubtree(q, p); - try { - deleteFileRecursively(q); - } catch (IOException ex) { - fb.error("ERR_CannotDeletePath", ex, p, ex.getMessage()); - } - } - } - - void deleteRecursively(Path listFile) throws IOException { - boolean first = true; - for (String fn : Files.readAllLines(listFile)) { - if (first) { - fb.message("MSG_DeleteObsoleteFiles"); - first = false; - } - Path p = SystemUtils.fromUserString(fn); - try { - deleteFileRecursively(p); - } catch (IOException ex) { - fb.error("ERR_CannotDeletePath", ex, p, ex.getMessage()); - } - } - } - - /** - * Also called from Uninstaller. - * - * @param rootPath root path to delete (inclusive) - * @throws IOException if the deletion fails. - */ - void deleteFileRecursively(Path rootPath) throws IOException { - try (Stream paths = Files.walk(rootPath)) { - paths.sorted(Comparator.reverseOrder()).forEach((p) -> { - if (!p.toAbsolutePath().startsWith(installPath)) { - return; - } - try { - fileOps.deleteFile(p); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }); - } catch (UncheckedIOException ex) { - throw ex.getCause(); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/AbstractCatalogStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/AbstractCatalogStorage.java deleted file mode 100644 index eab262f75f2f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/AbstractCatalogStorage.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.graalvm.component.installer.persist; - -import java.io.IOException; -import java.net.URL; -import java.util.Map; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.ComponentStorage; - -/** - * Base for different storage of remote component list. The default implementation uses properties - * resource reachable through the https. - * - * @author sdedic - */ -public abstract class AbstractCatalogStorage implements ComponentStorage { - protected final ComponentRegistry localRegistry; - protected final Feedback feedback; - protected final URL baseURL; - - public AbstractCatalogStorage(ComponentRegistry localRegistry, Feedback feedback, URL baseURL) { - this.localRegistry = localRegistry; - this.feedback = feedback; - this.baseURL = baseURL; - } - - @Override - public Map loadGraalVersionInfo() { - return localRegistry.getGraalCapabilities(); - } - - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - // files are not supported, yet - return ci; - } - - protected byte[] toHashBytes(String comp, String hashS) { - try { - return SystemUtils.toHashBytes(hashS); - } catch (IllegalArgumentException ex) { - throw new MetadataException(null, feedback.l10n("REMOTE_InvalidHash", comp, ex.getMessage())); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/Bundle.properties deleted file mode 100644 index 1710acd63dd7..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/Bundle.properties +++ /dev/null @@ -1,55 +0,0 @@ -ERROR_HeaderMissing=Required header is missing: {0} -ERROR_HeaderInvalid=Header {0} value is invalid: {1} -ERROR_MissingSymbolicName=Missing symbolic name -ERROR_InvalidSymbolicName=Invalid symbolic name -ERROR_ParametersUnsupported=Parameters are not supported -ERROR_InvalidVersion=Invalid version -ERROR_InvalidCapabilityName=Invalid capability name -ERROR_MissingCapabilityName=Missing capability name -# {0} - Directive or parameter name -ERROR_MissingArgument=Argument missing for directive or parameter {0} -# {0} - parameter name -ERROR_InvalidParameterSyntax=Invalid syntax for parameter or directive {0} -ERROR_InvalidQuotedString=Invalid quoted string -# {0} - parameter name -ERROR_MissingArgument=Missing argument for parameter or directive {0} -ERROR_InvalidVersion=Invalid version format -ERROR_InvalidParameterName=Invalid parameter or directive name -ERROR_UnsupportedParameters=Unsupported parameters found. -ERROR_UnsupportedDirectives=Unsupported directives found. -ERROR_MissingVersionFilter=Missing version filter -ERROR_InvalidFilterSpecification=Invalid filter specification -ERROR_UnknownCapability=Unsupported capability namespace -ERROR_UnsupportedFilterOperation=Unsupported operation in filter. Only = is supported. -ERROR_DuplicateFilterAttribute=Duplicate Filter Attribute - -ERROR_PermissionFormat=Invalid file permissions format -ERROR_BrokenSymlink=Symbolic link {0} is broken -ERROR_CircularSymlink=Symbolic link {0} forms a circular reference. -ERROR_CorruptedPackageMissingMeta=The package is corrupted, internal metadata is missing. -ERROR_UnsupportedCapabilityType=Unsupported type for capability {0}: {1} -ERROR_InvalidCapabilityVersion=Invalid version of capability {0}: {1} -ERROR_InvalidCapabilitySyntax=Invalid capability syntax -ERR_CannotReadAcceptance=Cannot read license acceptance info for {0}. -ERROR_DependencyParametersNotSupported=Parameters not supported for dependencies. - -ERR_DirectoryURLInvalid=Invalid or unreadable location on file system: {0}. The location will be ignored. - -# {0} - filename -# {1} - error message -ERR_DirectoryComponentMetadata=Component file {0} contains invalid or corrupted metadata, or is not a component: {1}. The file will be ignored. -ERR_DirectoryComponentError=Error loading component file {0}: {1}. The file will be ignored. - -DIR_LocalFile=Local file - -# {0} component distribution type -ERROR_InvalidDistributionType=Component {1}: invalid distribution type {0} - -# {0} license path -ERROR_CannotComputeLicenseID=Could not compute ID for license at {0}. - -# {0} the error message. -WARNING_CouldNotLoadPlugin=WARNING: could not load or initialize an extension: {0} - -LICENSE_RemoteLicenseDescription=Downloading license: {0} -ERROR_DownloadLicense=Could not download license {0}: {1} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/ComponentPackageLoader.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/ComponentPackageLoader.java deleted file mode 100644 index 61256fde7130..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/ComponentPackageLoader.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.BufferedReader; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.InstallerStopException; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.net.URL; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.PosixFilePermissions; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.function.Function; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * Loads information from the component's bundle. - */ -public class ComponentPackageLoader implements Closeable, MetadataLoader { - protected final Feedback feedback; - - /** - * Default value producer. - */ - private final Function valueSupplier; - - /** - * Do not throw exceptions eagerly. - */ - private boolean infoOnly; - - /** - * List of errors encountered when reading metadata. Filled only if {@link #infoOnly} = - * {@code true}. - */ - private final List errors = new ArrayList<>(); - private final List fileList = new ArrayList<>(); - - /** - * Component ID; temporary. - */ - private String id; - private String version; - private String name; - - /** - * Path for the LICENSE file; adjusted with version etc. - */ - private String licensePath; - - /** - * Type / name of the license. - */ - private String licenseType; - - /** - * The produced component info. - */ - private ComponentInfo info; - - /** - * If true, will not verify symbolic links. - * - * Default false = verify on. - */ - private boolean noVerifySymlinks; - - private final String componentTag; - - private final Properties props = new Properties(); - - static final ResourceBundle BUNDLE = ResourceBundle.getBundle("org.graalvm.component.installer.persist.Bundle"); - - public ComponentPackageLoader(String tag, Function supplier, Feedback feedback) { - this.feedback = feedback.withBundle(ComponentPackageLoader.class); - this.valueSupplier = supplier; - this.componentTag = tag; - } - - public ComponentPackageLoader(Function supplier, Feedback feedback) { - this(null, supplier, feedback); - } - - @Override - public Archive getArchive() { - return null; - } - - private String value(String key) { - String v = valueSupplier.apply(key); - if (v != null && (componentTag == null || componentTag.isEmpty())) { - props.put(key, v); - } - return v; - } - - @Override - public ComponentPackageLoader infoOnly(boolean only) { - this.infoOnly = only; - return this; - } - - private HeaderParser parseHeader(String header) throws MetadataException { - return parseHeader2(header, null); - } - - private HeaderParser parseHeader2(String header, Function fn) throws MetadataException { - String s = value(header); - if (fn != null) { - s = fn.apply(s); - } - return new HeaderParser(header, s, feedback).mustExist(); - } - - private HeaderParser parseHeader(String header, String defValue) throws MetadataException { - String s = value(header); - if (s == null) { - if (defValue == null) { - return new HeaderParser(header, s, feedback); - } else { - return new HeaderParser(header, defValue, feedback); - } - } - return new HeaderParser(header, s, feedback).mustExist(); - } - - @Override - public ComponentInfo getComponentInfo() { - if (info == null) { - return createComponentInfo(); - } - return info; - } - - private void parse(Runnable... parts) { - for (Runnable r : parts) { - try { - r.run(); - } catch (MetadataException ex) { - if (BundleConstants.BUNDLE_ID.equals(ex.getOffendingHeader())) { - throw ex; - } - if (infoOnly) { - errors.add(ex); - } else { - throw ex; - } - } catch (InstallerStopException ex) { - if (infoOnly) { - errors.add(ex); - } else { - throw ex; - } - } - } - } - - @Override - public List getErrors() { - return errors; - } - - /** - * Computes some component hash/tag. Computes a digest from each read/present value in the - * manifest. - */ - private void supplyComponentTag() { - String ct = info.getTag(); - if (ct != null && !ct.isEmpty()) { - return; - } - try (StringWriter wr = new StringWriter()) { - props.store(wr, ""); // NOI18N - info.setTag(SystemUtils.digestString(wr.toString().replaceAll("#.*\r?\n\r?", ""), false)); // NOI18N - } catch (IOException ex) { - throw new FailedOperationException(ex.getLocalizedMessage(), ex); - } - } - - private void loadWorkingDirectories(ComponentInfo nfo) { - String val = parseHeader(BundleConstants.BUNDLE_WORKDIRS, null).getContents(""); - Set workDirs = new LinkedHashSet<>(); - for (String s : val.split(":")) { // NOI18N - String p = s.trim(); - if (!p.isEmpty()) { - workDirs.add(p); - } - } - nfo.addWorkingDirectories(workDirs); - } - - private String findComponentTag() { - String t = value(BundleConstants.BUNDLE_SERIAL); - return t != null && !t.isEmpty() ? t : componentTag; - } - - protected ComponentInfo createBaseComponentInfo() { - parse( - () -> id = parseHeader(BundleConstants.BUNDLE_ID).parseSymbolicName(), - () -> name = parseHeader(BundleConstants.BUNDLE_NAME).getContents(id), - () -> version = parseHeader(BundleConstants.BUNDLE_VERSION).version(), - () -> { - info = new ComponentInfo(id, name, version, findComponentTag()); - info.addRequiredValues(parseHeader(BundleConstants.BUNDLE_REQUIRED).parseRequiredCapabilities()); - info.addProvidedValues(parseHeader(BundleConstants.BUNDLE_PROVIDED, "").parseProvidedCapabilities()); - info.setDependencies(parseHeader(BundleConstants.BUNDLE_DEPENDENCY, "").parseDependencies()); - info.setStability( - // use the new header, fall back on the old one. Default - // to "". - parseHeader(BundleConstants.BUNDLE_STABILITY2, value(BundleConstants.BUNDLE_STABILITY)).parseStability()); - }); - supplyComponentTag(); - return info; - } - - protected ComponentInfo loadExtendedMetadata(ComponentInfo base) { - parse( - () -> base.setDistributionType(parseDistributionType()), - () -> loadWorkingDirectories(base), - () -> loadMessages(base), - () -> loadLicenseType(base)); - return base; - } - - public ComponentInfo createComponentInfo() { - ComponentInfo nfo = createBaseComponentInfo(); - return loadExtendedMetadata(nfo); - } - - private DistributionType parseDistributionType() { - String dtString = parseHeader(BundleConstants.BUNDLE_COMPONENT_DISTRIBUTION, null).getContents(DistributionType.OPTIONAL.name()); - try { - return DistributionType.valueOf(dtString.toUpperCase(Locale.ENGLISH)); - } catch (IllegalArgumentException ex) { - // do not report the exception, just notice in verbose mode: - feedback.verboseOutput("ERROR_InvalidDistributionType", id, dtString); - return DistributionType.OPTIONAL; - } - } - - private void loadLicenseType(ComponentInfo nfo) { - licenseType = parseHeader(BundleConstants.BUNDLE_LICENSE_TYPE, null).getContents(null); - nfo.setLicenseType(licenseType); - if (licenseType != null) { - licensePath = parseHeader(BundleConstants.BUNDLE_LICENSE_PATH).mustExist().getContents(null); - nfo.setLicensePath(licensePath); - } - } - - @Override - public String getLicensePath() { - if (info != null) { - return info.getLicensePath(); - } - return licensePath; - } - - protected FileDownloader createFileDownloader(URL remote, String desc) { - return new FileDownloader(desc, remote, feedback); - } - - public String downloadAndHashLicense(String remote) { - String desc = getLicenseType(); - if (desc == null) { - desc = remote; - } - try { - URL u = SystemUtils.toURL(remote); - FileDownloader dn = createFileDownloader(u, feedback.l10n("LICENSE_RemoteLicenseDescription", desc)); - dn.download(); - String s = String.join("\n", Files.readAllLines(dn.getLocalFile().toPath())); - return SystemUtils.digestString(s, false) /* + "_" + remote */; - } catch (IOException ex) { - throw feedback.failure("ERROR_DownloadLicense", ex, desc, ex.getLocalizedMessage()); - } - } - - /** - * License digest or URL. - */ - private String cachedLicenseID; - - @Override - public String getLicenseID() { - if (cachedLicenseID != null) { - return cachedLicenseID; - } - String licPath = getLicensePath(); - if (licPath == null) { - return null; - } else if (SystemUtils.isRemotePath(licPath)) { // NOI18N - return cachedLicenseID = downloadAndHashLicense(licPath); - } - Archive.FileEntry foundEntry = null; - - for (Archive.FileEntry fe : getArchive()) { - if (getLicensePath().equals(fe.getName())) { - foundEntry = fe; - break; - } - } - if (foundEntry == null) { - throw feedback.failure("ERROR_CannotComputeLicenseID", null, licPath); - } - - ByteBuffer bb = ByteBuffer.allocate(Integer.getInteger("org.graalvm.component.installer.fileReadBuffer", 4096)); - MessageDigest dg; - String licId; - - try { - dg = MessageDigest.getInstance("SHA-256"); // NOI18N - } catch (NoSuchAlgorithmException ex) { - throw feedback.failure("ERROR_CannotComputeLicenseID", ex, foundEntry.getName()); - } - try (InputStream is = getArchive().getInputStream(foundEntry); - ReadableByteChannel rch = Channels.newChannel(is)) { - while (true) { - int read = rch.read(bb); - if (read < 0) { - break; - } - bb.flip(); - dg.update(bb); - bb.clear(); - } - licId = SystemUtils.fingerPrint(dg.digest(), false); - } catch (IOException ex) { - throw feedback.failure("ERROR_CannotComputeLicenseID", ex, foundEntry.getName()); - } - return cachedLicenseID = licId; - } - - @Override - public String getLicenseType() { - return licenseType; - } - - private void throwInvalidPermissions() { - throw feedback.failure("ERROR_PermissionFormat", null); - } - - @SuppressWarnings("unchecked") - protected Map parsePermissions(BufferedReader r) throws IOException { - Map result = new LinkedHashMap<>(); - - Properties prop = new Properties(); - prop.load(r); - - List paths = new ArrayList<>((Collection) Collections.list(prop.propertyNames())); - Collections.sort(paths); - - for (String k : paths) { - SystemUtils.fromCommonRelative(k); - String v = prop.getProperty(k, "").trim(); // NOI18N - if (!v.isEmpty()) { - try { - PosixFilePermissions.fromString(v); - } catch (IllegalArgumentException ex) { - throwInvalidPermissions(); - } - } - result.put(k, v); - } - return result; - } - - @Override - public Map loadPermissions() throws IOException { - return Collections.emptyMap(); - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - protected Map parseSymlinks(Properties links) { - for (String key : new HashSet<>(links.stringPropertyNames())) { - Path p = SystemUtils.fromCommonRelative(key).normalize(); - String prop = (String) links.remove(key); - links.setProperty(SystemUtils.toCommonPath(p), prop); - } - if (noVerifySymlinks) { - return new HashMap(links); - } - // check the links - for (String s : Collections.list((Enumeration) links.propertyNames())) { - String l = s; - Set seen = new HashSet<>(); - while (l != null) { - if (!seen.add(l)) { - throw feedback.failure("ERROR_CircularSymlink", null, l); - } - String target = links.getProperty(l); - Path linkPath = SystemUtils.fromCommonRelative(l); - SystemUtils.checkCommonRelative(linkPath, target); - Path targetPath = linkPath.resolveSibling(target).normalize(); - String targetString = SystemUtils.toCommonPath(targetPath); - if (fileList.contains(targetString)) { - break; - } - String lt = links.getProperty(targetString); - if (lt == null) { - throw feedback.failure("ERROR_BrokenSymlink", null, target); - } - l = targetString; - } - } - return new HashMap(links); - } - - @Override - public Map loadSymlinks() throws IOException { - return Collections.emptyMap(); - } - - @Override - public void loadPaths() { - getComponentInfo(); - } - - @Override - public boolean isNoVerifySymlinks() { - return noVerifySymlinks; - } - - @Override - public void setNoVerifySymlinks(boolean noVerifySymlinks) { - this.noVerifySymlinks = noVerifySymlinks; - } - - @Override - public void close() throws IOException { - } - - private void loadMessages(ComponentInfo nfo) { - String val = parseHeader(BundleConstants.BUNDLE_MESSAGE_POSTINST, null).getContents(null); - if (val != null) { - String text = val.replace("\\n", "\n").replace("\\\\", "\\"); // NOI18N - nfo.setPostinstMessage(text); - } - } - - protected void setLicensePath(String path) { - this.licensePath = path; - getComponentInfo().setLicensePath(licensePath); - } - - protected void addFiles(List files) { - fileList.addAll(files); - } - - @Override - public ComponentInfo completeMetadata() throws IOException { - return getComponentInfo(); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryCatalogProvider.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryCatalogProvider.java deleted file mode 100644 index a6f75c8fcf5a..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryCatalogProvider.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.Set; -import org.graalvm.component.installer.ComponentArchiveReader; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentStorage; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * Implements ComponentStorage over a local directory. It assumes that the directory contains JAR - * (or simply recognized formats) Components and turns them into a Storage. - *

- * It is then used as a part of {@link org.graalvm.component.installer.remote.MergeStorage} to - * provide source for a potential dependency of an installed Component. - *

- * This local storages should be added last, so that 'official' distributions win. - * - * @author sdedic - */ -public class DirectoryCatalogProvider implements ComponentStorage, SoftwareChannel { - private final Path directory; - private final Feedback feedback; - private boolean verifyJars = true; - private boolean reportErrors = true; - - /** - * Map componentID -> ComponentInfo. Lazy populated from {@link #initComponents()}. - */ - private Map> dirContents = null; - - public DirectoryCatalogProvider(Path directory, Feedback feedback) { - this.directory = directory; - this.feedback = feedback.withBundle(DirectoryCatalogProvider.class); - } - - public boolean isReportErrors() { - return reportErrors; - } - - public void setReportErrors(boolean reportErrors) { - this.reportErrors = reportErrors; - } - - public void setVerifyJars(boolean verifyJars) { - this.verifyJars = verifyJars; - } - - @Override - public Set listComponentIDs() throws IOException { - initComponents(); - return dirContents.keySet(); - } - - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - return ci; - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - initComponents(); - return dirContents.get(id); - } - - @Override - public Map loadGraalVersionInfo() { - initComponents(); - throw new UnsupportedOperationException("Not supported yet."); // To change body of - // generated methods, choose - // Tools | Templates. - } - - private void initComponents() { - if (dirContents != null) { - return; - } - - dirContents = new HashMap<>(); - if (!Files.isDirectory(directory)) { - return; - } - try { - Files.list(directory).forEach((p -> { - try { - ComponentInfo info = maybeCreateComponent(p); - if (info != null) { - dirContents.computeIfAbsent(info.getId(), (id) -> new HashSet<>()).add(info); - } - } catch (MetadataException ex) { - if (reportErrors) { - feedback.error("ERR_DirectoryComponentMetadata", ex, p.toString(), ex.getLocalizedMessage()); - } - } catch (IOException | FailedOperationException ex) { - if (reportErrors) { - feedback.error("ERR_DirectoryComponentError", ex, p.toString(), ex.getLocalizedMessage()); - } - } - })); - } catch (IOException ex) { - // report error, produce an empty - } - } - - private ComponentInfo maybeCreateComponent(Path localFile) throws IOException { - byte[] fileStart = null; - String serial; - - if (Files.isRegularFile(localFile)) { - try (ReadableByteChannel ch = FileChannel.open(localFile, StandardOpenOption.READ)) { - ByteBuffer bb = ByteBuffer.allocate(8); - ch.read(bb); - fileStart = bb.array(); - } - serial = SystemUtils.fingerPrint(SystemUtils.computeFileDigest(localFile, null)); - } else { - fileStart = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; - serial = SystemUtils.digestString(localFile.toString(), false); - } - MetadataLoader ldr = null; - try { - for (ComponentArchiveReader provider : ServiceLoader.load(ComponentArchiveReader.class)) { - ldr = provider.createLoader(localFile, fileStart, serial, feedback, verifyJars); - if (ldr != null) { - ComponentInfo info = ldr.getComponentInfo(); - info.setRemoteURL(localFile.toUri().toURL()); - info.setOrigin(feedback.l10n("DIR_LocalFile")); - return info; - } - } - } finally { - // ignore, may be not a component... - if (ldr != null) { - ldr.close(); - } - } - return null; - } - - @Override - public ComponentStorage getStorage() throws IOException { - return this; - } - - @Override - public FileDownloader configureDownloader(ComponentInfo info, FileDownloader dn) { - return dn; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryChannelFactory.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryChannelFactory.java deleted file mode 100644 index 25c504f1da65..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryChannelFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; - -/** - * Creates {@link DirectoryCatalogProvider}s over a directory. - * - * @author sdedic - */ -public class DirectoryChannelFactory implements SoftwareChannel.Factory { - @Override - public SoftwareChannel createChannel(SoftwareChannelSource source, CommandInput input, Feedback output) { - String u = source.getLocationURL(); - if (!u.startsWith("file:")) { // NOI18N - return null; - } - Feedback out2 = output.withBundle(DirectoryChannelFactory.class); - try { - Path p = new File(new URI(u)).toPath(); - if (!Files.isDirectory(p)) { - return null; - } - DirectoryCatalogProvider dp = new DirectoryCatalogProvider(p, out2); - dp.setVerifyJars(input.optValue(Commands.OPTION_NO_VERIFY_JARS) == null); - // do not report errors for directory sources implied by commandline arguments. - if (Boolean.FALSE.toString().equals(source.getParameter("reportErrors"))) { // NOI18N - dp.setReportErrors(false); - } - return dp; - } catch (URISyntaxException ex) { - out2.error("ERR_DirectoryURLInvalid", ex, u, ex.getMessage()); - return null; - } - } - - @Override - public void init(CommandInput input, Feedback output) { - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryStorage.java deleted file mode 100644 index 6d732b1db2d4..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/DirectoryStorage.java +++ /dev/null @@ -1,819 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringWriter; -import java.io.UncheckedIOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Config; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.model.ManagementStorage; -import org.graalvm.component.installer.model.StabilityLevel; - -/** - * Directory-based implementation of component storage. - */ -public class DirectoryStorage implements ManagementStorage { - public static final String META_LICENSE_FILE = "LICENSE_PATH"; // NOI18N - - /** - * Relative fileName for the "release" Graalvm metadata. - */ - private static final String PATH_RELEASE_FILE = "release"; - - /** - * Suffix for the component metadata files, including comma. - */ - private static final String COMPONENT_FILE_SUFFIX = ".component"; // NOI18N - - /** - * Metadata for natively installed component. - */ - private static final String NATIVE_COMPONENT_FILE_SUFFIX = ".meta"; // NOI18N - - /** - * Suffix for the filelist metadata files. - */ - private static final String LIST_FILE_SUFFIX = ".filelist"; // NOI18N - - /** - * The "replaced files" metadata fileName relative to the registry. - */ - private static final String PATH_REPLACED_FILES = "replaced-files.properties"; // NOI18N - - /** - * - * Template for license accepted records. - */ - private static final String LICENSE_DIR = "licenses"; // NOI18N' - - /** - * Template for license accepted records. - */ - private static final String LICENSE_CONTENTS_NAME = LICENSE_DIR + "/{0}"; // NOI18N' - - /** - * Template for license accepted records. - */ - private static final String LICENSE_CONTENTS_ID = LICENSE_DIR + "/{0}.id"; // NOI18N' - - /** - * - * Template for license accepted records. - */ - static final String LICENSE_FILE_TEMPLATE = LICENSE_DIR + "/{0}.accepted/_all"; // NOI18N' - - /** - * - */ - private static final String BUNDLE_REQUIRED_PREFIX = BundleConstants.BUNDLE_REQUIRED + "-"; // NOI18N - private static final String BUNDLE_PROVIDED_PREFIX = BundleConstants.BUNDLE_PROVIDED + "-"; // NOI18N - - /** - * Root of the storage fileName. - */ - protected final Path registryPath; - - /** - * GralVM installation home. - */ - protected final Path graalHomePath; - - /** - * The environment for reporting errors etc. - */ - private final Feedback feedback; - - private Properties loaded; - - private ComponentInfo graalCore; - - private static final String GRAALVM_SOURCE = "source"; // NOI18N - private static final Pattern SOURCE_REVISION = Pattern.compile("\\b([a-z-._]+):([0-9a-f]+)\\b"); // NOI18N - private static final String REVISION_PREFIX = "source_"; // NOI18N - - private static final String[] REQUIRED_ATTRIBUTES = { - CommonConstants.CAP_GRAALVM_VERSION, - CommonConstants.CAP_OS_NAME, - CommonConstants.CAP_OS_ARCH - }; - - private static final String ENTERPRISE_EDITION = "ee"; // NOI18N - private static final String VM_ENTERPRISE_COMPONENT = "vm-enterprise:"; // NOI18N - - private String javaVersion; - private Config config; - - public DirectoryStorage(Feedback feedback, Path storagePath, Path graalHomePath) { - this.feedback = feedback; - this.registryPath = storagePath; - this.graalHomePath = graalHomePath; - this.javaVersion = "" + SystemUtils.getJavaMajorVersion(); // NOI18N - } - - public Config getConfig() { - return config; - } - - public void setConfig(Config config) { - this.config = config; - } - - public String getJavaVersion() { - return javaVersion; - } - - public void setJavaVersion(String javaVersion) { - this.javaVersion = javaVersion; - } - - @Override - public Map loadGraalVersionInfo() { - Path graalVersionFile = graalHomePath.resolve(SystemUtils.fromCommonString(PATH_RELEASE_FILE)); - try (InputStream istm = Files.newInputStream(graalVersionFile)) { // NOI18N - return load(istm); - } catch (IOException ex) { - throw feedback.failure("ERROR_ReadingRealeaseFile", ex, graalVersionFile, ex.getMessage()); - } - } - - public Version getGraalVMVersion() { - String s = loadGraalVersionInfo().get(CommonConstants.CAP_GRAALVM_VERSION); - return Version.fromString(s); - } - - @SuppressWarnings("unchecked") - private Map load(InputStream istm) throws IOException { - Map graalAttributes = new HashMap<>(); - Properties props = new Properties(); - props.load(istm); - String srcText = null; - for (String key : Collections.list((Enumeration) props.propertyNames())) { - String val = props.getProperty(key, ""); // MOI18N - - String lowerKey = key.toLowerCase(Locale.ENGLISH); - if (!val.isEmpty() && val.charAt(0) == '"' && val.length() > 1 && val.charAt(val.length() - 1) == '"') { // MOI18N - val = val.substring(1, val.length() - 1).trim(); - } - if (GRAALVM_SOURCE.equals(lowerKey)) { - Matcher m = SOURCE_REVISION.matcher(val); - srcText = val; - while (m.find()) { - if (m.group(1) == null || m.group(2) == null || m.group(1).isEmpty() || m.group(2).isEmpty()) { - throw feedback.failure("ERROR_ReleaseSourceRevisions", null, graalHomePath); - } - graalAttributes.put(REVISION_PREFIX + m.group(1), m.group(2)); - } - } else { - graalAttributes.put(lowerKey, val); - } - } - for (String a : REQUIRED_ATTRIBUTES) { - if (!graalAttributes.containsKey(a)) { - throw feedback.failure("STORAGE_InvalidReleaseFile", null); - } - } - if (graalAttributes.get(CommonConstants.CAP_EDITION) == null && srcText != null) { - // Hardcoded, sorry ... - if (srcText.contains(VM_ENTERPRISE_COMPONENT)) { - graalAttributes.put(CommonConstants.CAP_EDITION, ENTERPRISE_EDITION); // NOI18N - } else { - graalAttributes.put(CommonConstants.CAP_EDITION, CommonConstants.EDITION_CE); - } - } - graalAttributes.putIfAbsent(CommonConstants.CAP_JAVA_VERSION, javaVersion); - return graalAttributes; - } - - /** - * Loads list of components. - * - * @return component IDs - * @throws IOException - */ - @Override - public Set listComponentIDs() throws IOException { - if (!Files.exists(registryPath)) { - return Collections.emptySet(); - } - File d = registryPath.toFile(); - File[] files = d.listFiles(new FileFilter() { - @Override - public boolean accept(File child) { - if (!Files.isRegularFile(child.toPath())) { - return false; - } - return child.getName().endsWith(COMPONENT_FILE_SUFFIX) || - child.getName().endsWith(NATIVE_COMPONENT_FILE_SUFFIX); - } - }); - if (files != null) { - Set result = new HashSet<>(); - for (File f : files) { - String s = registryPath.relativize(f.toPath()).toString(); - int lastDot = s.lastIndexOf('.'); - result.add(s.substring(0, lastDot)); - } - // GraalVM core is always present - if (Files.exists(graalHomePath.resolve("bin"))) { - result.add(BundleConstants.GRAAL_COMPONENT_ID); - } - return result; - } else { - throw new IllegalArgumentException("File listing of " + d + " returned null."); - } - } - - private static String computeTag(Properties data) throws IOException { - try (StringWriter wr = new StringWriter()) { - data.store(wr, ""); - // properties store date/time into the stream as a comment. Cannot be disabled - // programmatically, - // must filter out. - return SystemUtils.digestString(wr.toString().replaceAll("#.*\r?\n\r?", ""), false); // NOI18N - } - } - - ComponentInfo loadMetadataFrom(InputStream fileStream) throws IOException { - loaded = new Properties(); - loaded.load(fileStream); - - String serial = loaded.getProperty(BundleConstants.BUNDLE_SERIAL); - if (serial == null) { - serial = computeTag(loaded); - } - String id = getRequiredProperty(BundleConstants.BUNDLE_ID); - String name = getRequiredProperty(BundleConstants.BUNDLE_NAME); - String version = getRequiredProperty(BundleConstants.BUNDLE_VERSION); - - return propertiesToMeta(loaded, new ComponentInfo(id, name, version, serial), feedback); - } - - public static ComponentInfo propertiesToMeta(Properties loaded, ComponentInfo ci, Feedback fb) { - String stability = loaded.getProperty(BundleConstants.BUNDLE_STABILITY2, loaded.getProperty(BundleConstants.BUNDLE_STABILITY)); - if (stability != null) { - ci.setStability(StabilityLevel.valueOfMixedCase(stability)); - } - String license = loaded.getProperty(BundleConstants.BUNDLE_LICENSE_PATH); - if (license != null) { - SystemUtils.checkCommonRelative(null, license); - ci.setLicensePath(license); - } - for (String s : loaded.stringPropertyNames()) { - if (s.startsWith(BUNDLE_REQUIRED_PREFIX)) { - String k = s.substring(BUNDLE_REQUIRED_PREFIX.length()); - String v = loaded.getProperty(s, ""); // NOI18N - ci.addRequiredValue(k, v); - } - if (s.startsWith(BUNDLE_PROVIDED_PREFIX)) { - String k = s.substring(BUNDLE_PROVIDED_PREFIX.length()); - String v = loaded.getProperty(s, ""); // NOI18N - if (v.length() < 2) { - continue; - } - String val = v.substring(1); - Object o; - switch (v.charAt(0)) { - case 'V': - o = Version.fromString(val); - break; - case '"': - o = val; - break; - default: - continue; - } - ci.provideValue(k, o); - } - } - Set deps = new LinkedHashSet<>(); - for (String s : loaded.getProperty(BundleConstants.BUNDLE_DEPENDENCY, "").split(",")) { - String p = s.trim(); - if (!p.isEmpty()) { - deps.add(s.trim()); - } - } - if (!deps.isEmpty()) { - ci.setDependencies(deps); - } - List ll = new ArrayList<>(); - for (String s : loaded.getProperty(BundleConstants.BUNDLE_WORKDIRS, "").split(":")) { - String p = s.trim(); - if (!p.isEmpty()) { - SystemUtils.checkCommonRelative(null, p); - ll.add(p); - } - } - ci.addWorkingDirectories(ll); - String licType = loaded.getProperty(BundleConstants.BUNDLE_LICENSE_TYPE); - if (licType != null) { - ci.setLicenseType(licType); - } - String postInst = loaded.getProperty(BundleConstants.BUNDLE_MESSAGE_POSTINST); - if (postInst != null) { - String text = postInst.replace("\\n", "\n").replace("\\\\", "\\"); // NOI18N - ci.setPostinstMessage(text); - } - String u = loaded.getProperty(CommonConstants.BUNDLE_ORIGIN_URL); - if (u != null) { - try { - ci.setRemoteURL(SystemUtils.toURL(u)); - } catch (MalformedURLException ex) { - // ignore - } - } - String dtn = loaded.getProperty(BundleConstants.BUNDLE_COMPONENT_DISTRIBUTION, DistributionType.OPTIONAL.name()); - try { - ci.setDistributionType(DistributionType.valueOf(dtn.toUpperCase(Locale.ENGLISH))); - } catch (IllegalArgumentException ex) { - throw new MetadataException(BundleConstants.BUNDLE_COMPONENT_DISTRIBUTION, - fb.withBundle(DirectoryStorage.class).l10n("ERROR_InvalidDistributionType", dtn)); - } - return ci; - } - - private ComponentInfo getCoreInfo() { - if (graalCore != null) { - return graalCore; - } - - ComponentInfo ci = null; - try { - Path cmpFile = registryPath.resolve(SystemUtils.fileName(BundleConstants.GRAAL_COMPONENT_ID + COMPONENT_FILE_SUFFIX)); - if (Files.isReadable(cmpFile)) { - ci = doLoadComponentMetadata(cmpFile, false); - if (ci != null && !BundleConstants.GRAAL_COMPONENT_ID.equals(ci.getId())) { - // invalid definition - ci = null; - } - } - } catch (IOException ex) { - // ignore - } - if (ci == null) { - Version v = getGraalVMVersion(); - ci = new ComponentInfo(BundleConstants.GRAAL_COMPONENT_ID, - feedback.l10n("NAME_GraalCoreComponent"), v.originalString()); - // set defaults: bundled, supported. - ci.setStability(StabilityLevel.Supported); - } - Path cmpFile = registryPath.resolve(SystemUtils.fileName(BundleConstants.GRAAL_COMPONENT_ID + NATIVE_COMPONENT_FILE_SUFFIX)); - if (Files.exists(cmpFile)) { - ci.setNativeComponent(true); - } - ci.setDistributionType(DistributionType.BUNDLED); - graalCore = ci; - return graalCore; - } - - @Override - public Set loadComponentMetadata(String tag) throws IOException { - Path cmpFile = registryPath.resolve(SystemUtils.fileName(tag + COMPONENT_FILE_SUFFIX)); - boolean nc = false; - if (BundleConstants.GRAAL_COMPONENT_ID.equals(tag)) { - return Collections.singleton(getCoreInfo()); - } - if (!Files.exists(cmpFile)) { - cmpFile = registryPath.resolve(SystemUtils.fileName(tag + NATIVE_COMPONENT_FILE_SUFFIX)); - if (!Files.exists(cmpFile)) { - return null; - } - nc = true; - } - return Collections.singleton(doLoadComponentMetadata(cmpFile, nc)); - } - - private ComponentInfo doLoadComponentMetadata(Path cmpFile, boolean nc) throws IOException { - try (InputStream fileStream = Files.newInputStream(cmpFile)) { - ComponentInfo info = loadMetadataFrom(fileStream); - info.setInfoPath(cmpFile.toString()); - info.setNativeComponent(nc); - return info; - } - } - - /** - * Loads component files into its metadata. - * - * @param ci the component metadata - * @return initialized ComponentInfo - * @throws IOException on I/O errors - */ - @Override - public ComponentInfo loadComponentFiles(ComponentInfo ci) throws IOException { - String tag = ci.getId(); - Path listFile = registryPath.resolve(SystemUtils.fileName(tag + LIST_FILE_SUFFIX)); - if (!Files.exists(listFile)) { - return ci; - } - List s = Files.readAllLines(listFile); - // throw away duplicities, sort. - Set result = new HashSet<>(s.size()); - for (String e : s) { - String trimmed = e.trim(); - if (!trimmed.isEmpty()) { - SystemUtils.checkCommonRelative(null, trimmed); - result.add(trimmed); - } - } - s = new ArrayList<>(result); - Collections.sort(s); - ci.addPaths(s); - return ci; - } - - private String getRequiredProperty(String key) { - String val = loaded.getProperty(key); - if (val == null) { - throw feedback.failure("STORAGE_CorruptedComponentStorage", null); - } - return val; - } - - @Override - @SuppressWarnings("unchecked") - public Map> readReplacedFiles() throws IOException { - Path replacedPath = registryPath.resolve(SystemUtils.fromCommonString(PATH_REPLACED_FILES)); - Map> result = new HashMap<>(); - Properties props = new Properties(); - if (!Files.exists(replacedPath)) { - return result; - } - try (InputStream is = Files.newInputStream(replacedPath)) { - props.load(is); - } - for (String s : Collections.list((Enumeration) props.propertyNames())) { - String files = props.getProperty(s, ""); // NOI18N - Collection unsorted = new HashSet<>(); - for (String x : files.split(" *, *")) { // NOI18N - String t = x.trim(); - if (!t.isEmpty()) { - SystemUtils.checkCommonRelative(null, t); - unsorted.add(t); - } - } - List components = new ArrayList<>(unsorted); - Collections.sort(components); - result.put(s, components); - } - return result; - } - - @Override - public void updateReplacedFiles(Map> replacedFiles) throws IOException { - Properties props = new SortedProperties(); - for (String k : replacedFiles.keySet()) { - List ids = new ArrayList<>(replacedFiles.get(k)); - Collections.sort(ids); - props.setProperty(k, String.join(",", ids)); - } - Path replacedPath = registryPath.resolve(SystemUtils.fromCommonString(PATH_REPLACED_FILES)); - if (props.isEmpty()) { - Files.deleteIfExists(replacedPath); - } else { - try (OutputStream os = Files.newOutputStream(replacedPath, - StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { - props.store(os, null); - } - } - } - - /** - * Deletes component's files. - * - * @param id component id - * @throws IOException - */ - @Override - public void deleteComponent(String id) throws IOException { - Path compFile = registryPath.resolve(SystemUtils.fileName(id + COMPONENT_FILE_SUFFIX)); - Path listFile = registryPath.resolve(SystemUtils.fileName(id + LIST_FILE_SUFFIX)); - Files.deleteIfExists(compFile); - Files.deleteIfExists(listFile); - } - - /** - * Will persist component's metadata. - * - * @param info - * @throws IOException on failure - */ - @Override - public void saveComponent(ComponentInfo info) throws IOException { - // hack: if the component is null, just verify that the user has access to the registry's - // data - verifyUserAccess(); - if (info == null) { - return; - } - if (info.isNativeComponent()) { - return; - } - Path cmpFile = registryPath.resolve(SystemUtils.fileName(info.getId() + COMPONENT_FILE_SUFFIX)); - try (OutputStream compFile = Files.newOutputStream(cmpFile, StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING)) { - metaToProperties(info).store(compFile, null); - } - saveComponentFileList(info); - } - - public static Properties metaToProperties(ComponentInfo info) { - SortedProperties p = new SortedProperties(); - p.setProperty(BundleConstants.BUNDLE_ID, info.getId()); - p.setProperty(BundleConstants.BUNDLE_NAME, info.getName()); - p.setProperty(BundleConstants.BUNDLE_VERSION, info.getVersionString()); - String s = info.getTag(); - if (s != null && !s.isEmpty()) { - p.setProperty(BundleConstants.BUNDLE_SERIAL, s); - } - if (info.getLicensePath() != null) { - p.setProperty(BundleConstants.BUNDLE_LICENSE_PATH, info.getLicensePath()); - } - if (info.getLicenseType() != null) { - p.setProperty(BundleConstants.BUNDLE_LICENSE_TYPE, info.getLicenseType()); - } - if (info.getStability() != StabilityLevel.Undefined) { - p.setProperty(BundleConstants.BUNDLE_STABILITY2, info.getStability().toString()); - } - for (String k : info.getRequiredGraalValues().keySet()) { - String v = info.getRequiredGraalValues().get(k); - if (v == null) { - v = ""; // NOI18N - } - p.setProperty(BUNDLE_REQUIRED_PREFIX + k, v); - } - for (String k : info.getProvidedValues().keySet()) { - Object o = info.getProvidedValue(k, Object.class); - char t; - if (o instanceof String) { - t = '"'; // NOI18N - } else if (o instanceof Version) { - t = 'V'; - o = ((Version) o).originalString(); - } else { - continue; - } - p.setProperty(BUNDLE_PROVIDED_PREFIX + k, t + o.toString()); - } - if (!info.getDependencies().isEmpty()) { - p.setProperty(BundleConstants.BUNDLE_DEPENDENCY, info.getDependencies().stream().sequential().collect(Collectors.joining(","))); - } - if (info.getPostinstMessage() != null) { - p.setProperty(BundleConstants.BUNDLE_MESSAGE_POSTINST, info.getPostinstMessage()); - } - if (!info.getWorkingDirectories().isEmpty()) { - p.setProperty(BundleConstants.BUNDLE_WORKDIRS, info.getWorkingDirectories().stream().sequential().collect(Collectors.joining(":"))); - } - if (info.getDistributionType() != DistributionType.OPTIONAL) { - p.setProperty(BundleConstants.BUNDLE_COMPONENT_DISTRIBUTION, info.getDistributionType().name().toLowerCase(Locale.ENGLISH)); - } - URL u = info.getRemoteURL(); - if (u != null) { - p.setProperty(CommonConstants.BUNDLE_ORIGIN_URL, u.toString()); - } - return p; - } - - void saveComponentFileList(ComponentInfo info) throws IOException { - Path listFile = registryPath.resolve(SystemUtils.fileName(info.getId() + LIST_FILE_SUFFIX)); - List entries = new ArrayList<>(new HashSet<>(info.getPaths())); - Collections.sort(entries); - - Files.write(listFile, entries, StandardOpenOption.CREATE, - StandardOpenOption.TRUNCATE_EXISTING); - } - - private static String transliterateLicenseId(String licenseID) { - return licenseID.replaceAll("[^-\\p{Alnum}.,_()@^{}~]", "_"); - } - - @Override - public Date licenseAccepted(ComponentInfo info, String licenseID) { - if (!SystemUtils.isLicenseTrackingEnabled()) { - return null; - } - String id = transliterateLicenseId(licenseID); - try { - String fn = MessageFormat.format(LICENSE_FILE_TEMPLATE, id, info == null ? "_all" : info.getId()); - Path listFile = registryPath.resolve(SystemUtils.fromCommonRelative(fn)); - if (!Files.isReadable(listFile)) { - return null; - } - return new Date(Files.getLastModifiedTime(listFile).toMillis()); - } catch (IOException ex) { - throw feedback.failure("ERR_CannotReadAcceptance", ex, licenseID); - } - } - - @Override - public Map> findAcceptedLicenses() { - if (!SystemUtils.isLicenseTrackingEnabled()) { - return Collections.emptyMap(); - } - Path licDir = registryPath.resolve(LICENSE_DIR); - Map> result = new HashMap<>(); - try { - if (!Files.isDirectory(licDir)) { - return Collections.emptyMap(); - } - Files.walk(licDir).forEach((lp) -> { - if (!Files.isRegularFile(lp)) { - return; - } - Path parent = lp.getParent(); - if (parent.equals(licDir)) { - return; - } - String fn = parent.getFileName().toString(); - if (!fn.endsWith(".accepted")) { - return; - } - int dot = fn.lastIndexOf('.'); - String fnid = fn.substring(0, dot); - String id; - try { - Path p = registryPath.resolve(SystemUtils.fromCommonRelative(MessageFormat.format(LICENSE_CONTENTS_ID, fnid))); - if (Files.exists(p)) { - List lines = Files.readAllLines(p); - id = lines.get(0); - } else { - id = fnid; - } - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - result.computeIfAbsent(id, (x) -> new ArrayList<>()).add(lp.getFileName().toString()); - }); - } catch (UncheckedIOException ex) { - throw feedback.failure("ERR_CannotReadAcceptance", ex.getCause(), "(all)"); - } catch (IOException ex) { - throw feedback.failure("ERR_CannotReadAcceptance", ex, "(all)"); - } - return result; - } - - @Override - public void recordLicenseAccepted(ComponentInfo info, String licenseID, String licenseText, Date d) throws IOException { - if (!SystemUtils.isLicenseTrackingEnabled()) { - return; - } - if (licenseID == null) { - clearRecordedLicenses(); - return; - } - String id = transliterateLicenseId(licenseID); - String fn = MessageFormat.format(LICENSE_FILE_TEMPLATE, id, info == null ? "_all" : info.getId()); - Path listFile = registryPath.resolve(SystemUtils.fromCommonRelative(fn)); - if (listFile == null) { - throw new IllegalArgumentException(licenseID); - } - Path dir = listFile.getParent(); - if (dir == null) { - throw new IllegalArgumentException(licenseID); - } - if (!Files.isDirectory(dir)) { - // create the directory - Files.createDirectories(dir); - Path contentsFile = registryPath.resolve(SystemUtils.fromCommonRelative( - MessageFormat.format(LICENSE_CONTENTS_NAME, id))); - Files.write(contentsFile, Arrays.asList(licenseText.split("\n"))); - if (!id.equals(licenseID)) { - Path p = registryPath.resolve(SystemUtils.fromCommonRelative(MessageFormat.format(LICENSE_CONTENTS_ID, id))); - Files.write(p, Arrays.asList(licenseID)); - } - } - String ds = (d == null ? new Date() : d).toString(); - Files.write(listFile, Collections.singletonList(ds), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - } - - void clearRecordedLicenses() throws IOException { - Path listFile = registryPath.resolve(LICENSE_DIR); - if (Files.isDirectory(listFile)) { - try (Stream paths = Files.walk(listFile)) { - paths.sorted(Comparator.reverseOrder()).forEach((p) -> { - try { - if (p.equals(listFile)) { - return; - } - Files.delete(p); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }); - } catch (UncheckedIOException ex) { - throw ex.getCause(); - } - } - } - - @Override - public String licenseText(String licID) { - Path contentsFile = registryPath.resolve(SystemUtils.fromCommonRelative( - MessageFormat.format(LICENSE_CONTENTS_NAME, transliterateLicenseId(licID)))); - try { - return Files.lines(contentsFile).collect(Collectors.joining("\n")); - } catch (IOException ex) { - throw feedback.failure("ERR_CannotReadAcceptance", ex, licID); - } - } - - void verifyUserAccess() { - if (Files.isWritable(registryPath)) { - return; - } - try { - String owner = SystemUtils.findFileOwner(registryPath); - if (owner != null) { - throw feedback.failure("ERROR_MustBecomeUser", null, owner); - } - } catch (IOException ex) { - // ignore, use generic message - } - throw feedback.failure("ERROR_MustBecomeAdmin", null); - } - - @Override - public int hashCode() { - int hash = 3; - hash = 97 * hash + Objects.hashCode(this.graalHomePath); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final DirectoryStorage other = (DirectoryStorage) obj; - if (!Objects.equals(this.graalHomePath, other.graalHomePath)) { - return false; - } - return true; - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/HeaderParser.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/HeaderParser.java deleted file mode 100644 index 85c909b398ef..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/HeaderParser.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.util.Collections; -import org.graalvm.component.installer.MetadataException; -import org.graalvm.component.installer.DependencyException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.function.Predicate; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.StabilityLevel; - -/** - * Parses OSGI-like metadata in JAR component bundles. - */ -public class HeaderParser { - private static final String DIRECTIVE_FILTER = "filter"; // NOI18N - - private final String headerName; - private final Map parameters = new HashMap<>(); - private final Map directives = new HashMap<>(); - private final Map filterValue = new HashMap<>(); - private final Map capabilities = new HashMap<>(); - private final Set dependencies = new HashSet<>(); - private final Feedback feedback; - - private String header; - private int pos; - private String directiveOrParameterName; - private int contentStart; - private String versionFilter; - - // static final ResourceBundle BUNDLE = - // ResourceBundle.getBundle("org.graalvm.component.installer.persist.Bundle"); - - public HeaderParser(String headerName, String header, Feedback feedback) { - this.headerName = headerName; - this.feedback = feedback.withBundle(HeaderParser.class); - - if (header != null) { - // trim whitespaces; - this.header = header.trim(); - } else { - this.header = ""; - } - } - - private MetadataException metaEx(String key, Object... args) { - return new MetadataException(headerName, feedback.l10n(key, args)); - } - - public HeaderParser mustExist() throws MetadataException { - if (header == null || header.isEmpty()) { - throw metaEx("ERROR_HeaderMissing", headerName); - } - return this; - } - - private static boolean isAlphaNum(char c) { - return (c >= '0' && c <= '9') || // NOI18N - (c >= 'A' && c <= 'Z') || // NOI18N - (c >= 'a' && c <= 'z'); // NOI18N - } - - private static boolean isToken(char c) { - return isAlphaNum(c) || c == '_' || c == '-'; // NOI18N - } - - private static boolean isExtended(char c) { - return isToken(c) || c == '.'; - } - - public boolean getBoolean(Boolean defValue) { - if (pos >= header.length()) { - if (defValue == null) { - throw metaEx("ERROR_HeaderMissing", headerName); // NOI18N - } - return defValue; - } else { - String s = header.substring(pos).trim().toLowerCase(Locale.ENGLISH); - switch (s) { - case "true": // NOI18N - return true; - case "false": // NOI18N - return false; - } - throw metaEx("ERROR_HeaderInvalid", headerName, s); // NOI18N - } - } - - public String getContents(String defValue) { - if (pos >= header.length()) { - return defValue; - } else { - return header.substring(pos).trim(); - } - } - - private void addFilterAttribute(String attrName, String value) { - if (filterValue.put(attrName, value) != null) { - throw metaErr("ERROR_DuplicateFilterAttribute"); - } - } - - private boolean isEmpty() { - return pos >= header.length(); - } - - public String parseSymbolicName() throws MetadataException { - return parseNameOrNamespace(HeaderParser::isToken, "ERROR_MissingSymbolicName", "ERROR_InvalidSymbolicName", '.'); - } - - private char next() { - return pos < header.length() ? header.charAt(pos++) : 0; - } - - private void advance() { - pos++; - } - - private char ch() { - return isEmpty() ? 0 : header.charAt(pos); - } - - private String returnCut() { - String s = cut(); - skipWhitespaces(); - return s; - } - - private void skipWhitespaces() { - while (!isEmpty()) { - if (!Character.isWhitespace(ch())) { - contentStart = pos; - return; - } - advance(); - } - contentStart = -1; - } - - private void skipWithSemicolon() { - skipWhitespaces(); - if (ch() == ';') { - advance(); - } - contentStart = -1; - } - - private String cut() { - return cut(0); - } - - private String cut(int delim) { - int e = pos - delim; - return contentStart == -1 || contentStart >= e ? "" : header.substring(contentStart, e); // NOI18N - } - - private void markContent() { - contentStart = pos; - } - - private String readExtendedParameter() throws MetadataException { - skipWhitespaces(); - while (!isEmpty()) { - char c = next(); - if (Character.isWhitespace(c)) { - break; - } - if (c == ';') { - pos--; - break; - } - if (!isExtended(c)) { - throw metaEx("ERROR_InvalidParameterSyntax", directiveOrParameterName); - } - } - String s = cut(); - skipWithSemicolon(); - return s; - } - - private String readQuotedParameter() throws MetadataException { - markContent(); - while (!isEmpty()) { - char c = next(); - switch (c) { - case '"': - String s = cut(1); - skipWithSemicolon(); - return s; - case '\n': - case '\r': - case 0: - throw metaEx("ERROR_InvalidQuotedString"); - case '\\': - next(); - break; - } - } - throw metaEx("ERROR_InvalidQuotedString"); - } - - private String parseArgument() throws MetadataException { - skipWhitespaces(); - char c = ch(); - if (c == ';') { - throw metaEx("ERROR_MissingArgument", directiveOrParameterName); - } - if (c == '"') { // NOI18N - advance(); - return readQuotedParameter(); - } else { - return readExtendedParameter(); - } - } - - private String parseNameOrNamespace(Predicate charAcceptor, - String missingKeyName, String invalidKeyName, char compDelimiter) throws MetadataException { - if (header == null || isEmpty()) { - throw metaEx(missingKeyName); - } - skipWhitespaces(); - boolean componentEmpty = true; - while (!isEmpty()) { - char c = ch(); - if (c == ';' || c == ',') { - String s = cut(); - return s; - } - advance(); - if (c == compDelimiter) { - if (componentEmpty) { - throw metaEx(invalidKeyName); - } - componentEmpty = true; - continue; - } - if (Character.isWhitespace(c)) { - break; - } - if (!charAcceptor.test(c)) { - throw metaEx(invalidKeyName); - } - componentEmpty = false; - } - return returnCut(); - } - - private String parseNamespace() throws MetadataException { - return parseNameOrNamespace(HeaderParser::isExtended, "ERROR_MissingCapabilityName", "ERROR_InvalidCapabilityName", (char) 0); - } - - /** - * Parses version at the current position. - */ - public String version() throws MetadataException { - int versionStart = -1; - int partCount = 0; - boolean partContents = false; - if (isEmpty()) { - throw metaErr("ERROR_InvalidVersion"); - } - boolean dash = false; - while (!isEmpty()) { - char c = ch(); - - if (Character.isWhitespace(c)) { - if (versionStart != -1) { - break; - } - advance(); - continue; - } - - if (c == ';') { - break; - } - advance(); - if (c == '.') { - ++partCount; - if (!partContents) { - throw metaErr("ERROR_InvalidVersion"); - } - partContents = false; - dash = false; - continue; - } - if (partCount > 0 && partContents && c == '-') { - dash = true; - continue; - } - if (c >= '0' && c <= '9') { - if (versionStart == -1) { - versionStart = pos - 1; - } - } else { - if (partCount < 1) { - throw metaErr("ERROR_InvalidVersion"); - } - boolean err = false; - if (partCount >= 3 || dash) { - err = !isToken(c); - } else { - err = true; - } - if (err) { - throw metaErr("ERROR_InvalidVersion"); - } - } - partContents = true; - } - String v = cut(); - skipWhitespaces(); - if (!isEmpty() || !partContents) { - throw metaErr("ERROR_InvalidVersion"); - } - - return v; - } - - private String readExtendedName() { - skipWhitespaces(); - while (!isEmpty()) { - char c = ch(); - if (isExtended(c)) { - advance(); - } else if (Character.isWhitespace(c) || c == ':' || c == '=' || c == ';') { - break; - } else { - throw metaEx("ERROR_InvalidParameterName"); - } - } - return returnCut(); - } - - private void parseParameters() { - while (!isEmpty()) { - String paramOrDirectiveName = readExtendedName(); - if (paramOrDirectiveName.isEmpty()) { - throw metaEx("ERROR_InvalidParameterName"); - } - directiveOrParameterName = paramOrDirectiveName; - - char c = ch(); - boolean dcolon = c == ':'; // NOI18N - if (dcolon) { - advance(); - } - c = next(); - if (c != '=') { // NOI18N - throw metaEx("ERROR_InvalidParameterSyntax", paramOrDirectiveName); - } - (dcolon ? directives : parameters).put(paramOrDirectiveName, parseArgument()); - } - } - - private void replaceInputText(String text) { - this.header = text; - this.pos = 0; - } - - private MetadataException metaErr(String key, Object... args) throws MetadataException { - throw metaEx(key, args); - } - - private MetadataException filterError() throws MetadataException { - throw metaErr("ERROR_InvalidFilterSpecification"); - } - - private void parseFilterConjunction() { - skipWhitespaces(); - char c = next(); - while (c == '(') { - parseFilterContent(); - c = next(); - } - if (c != ')') { - throw filterError(); - } - } - - private void parseFilterClause() { - skipWhitespaces(); - int lastPos = -1; - W: while (!isEmpty()) { - char c = ch(); - if (Character.isWhitespace(c)) { - if (lastPos == -1) { - lastPos = pos; - } - continue; - } - switch (c) { - case '=': - case '<': - case '>': - case '~': - case '(': - case ')': - break W; - } - lastPos = -1; - advance(); - } - - String attributeName = returnCut(); - char c = next(); - if (c != '=') { - throw metaErr("ERROR_UnsupportedFilterOperation"); - } - c = ch(); - if (c == '*') { - throw metaErr("ERROR_UnsupportedFilterOperation"); - } - markContent(); - while (!isEmpty()) { - c = next(); - if (c == ')') { - addFilterAttribute(attributeName, cut(1)); - skipWhitespaces(); - return; - } - - switch (c) { - case '\\': - c = next(); - if (c == 0) { - throw filterError(); - } - break; - case '*': - throw metaErr("ERROR_UnsupportedFilterOperation"); - case '(': - case '<': - case '>': - case '~': - case '=': - throw filterError(); - } - } - throw filterError(); - } - - private void parseFilterContent() { - skipWhitespaces(); - char o = ch(); - if (o == '&') { - advance(); - parseFilterConjunction(); - } else if (isExtended(o)) { - parseFilterClause(); - } else { - throw metaErr("ERROR_InvalidFilterSpecification"); - } - } - - private void parseFilterSpecification() { - skipWhitespaces(); - if (isEmpty()) { - throw filterError(); - } - char c = next(); - if (c == '(') { - parseFilterContent(); - skipWhitespaces(); - if (!isEmpty()) { - throw metaErr("ERROR_InvalidFilterSpecification"); - } - } else { - throw filterError(); - } - } - - /** - * Parses required capabilities string. - * - * org.graalvm; filter:="(&(graalvm_version=0.32)(os_name=linux)(os_arch=amd64))" - * - * @return graal capabilities - * @throws MetadataException - */ - public Map parseRequiredCapabilities() { - String namespace = parseNamespace(); - - char c = next(); - if (c != ';' && c != 0) { - throw metaErr("ERROR_InvalidFilterSpecification"); - } - - if (!BundleConstants.GRAALVM_CAPABILITY.equals(namespace)) { - // unsupported capability - throw new MetadataException(BundleConstants.BUNDLE_REQUIRED, feedback.l10n("ERROR_UnknownCapability")); - } - parseParameters(); - - if (!parameters.isEmpty()) { - throw metaErr("ERROR_UnsupportedParameters"); - } - versionFilter = directives.remove(DIRECTIVE_FILTER); - if (!directives.isEmpty()) { - throw metaErr("ERROR_UnsupportedDirectives"); - } - if (versionFilter == null) { - throw metaErr("ERROR_MissingVersionFilter"); - } - - // replace the input text, the rest of header will be ignored - replaceInputText(versionFilter); - parseFilterSpecification(); - - return filterValue; - } - - public Map parseProvidedCapabilities() { - if (isEmpty()) { - return Collections.emptyMap(); - } - String namespace = parseNamespace(); - - char c = next(); - if (c != ';' && c != 0) { - throw metaErr("ERROR_InvalidCapabilitySyntax"); - } - - if (!BundleConstants.GRAALVM_CAPABILITY.equals(namespace)) { - // unsupported capability - throw new DependencyException(namespace, null, null, feedback.l10n("ERROR_UnknownCapability")); - } - while (!isEmpty()) { - parseCapability(); - } - return capabilities; - } - - public StabilityLevel parseStability() { - if (isEmpty()) { - return StabilityLevel.Undefined; - } - return StabilityLevel.valueOfMixedCase(getContents("")); - } - - public Set parseDependencies() { - if (isEmpty()) { - return Collections.emptySet(); - } - while (!isEmpty()) { - String sn = parseSymbolicName(); - dependencies.add(sn); - skipWhitespaces(); - if (isEmpty()) { - break; - } - char c = next(); - switch (c) { - case ',': - // OK - break; - case ';': - throw metaEx("ERROR_DependencyParametersNotSupported"); - } - } - return dependencies; - } - - private void parseCapability() { - String capName = readExtendedName(); - if (capName.isEmpty()) { - throw metaEx("ERROR_InvalidCapabilityName"); - } - directiveOrParameterName = capName; - - char c = next(); - boolean dcolon = c == ':'; // NOI18N - boolean makeVersion = false; - if (dcolon) { - if (ch() == '=') { - throw metaEx("ERROR_InvalidCapabilitySyntax", capName); - } - skipWhitespaces(); - while (true) { - if (isEmpty()) { - throw metaEx("ERROR_InvalidCapabilitySyntax", capName); - } - c = next(); - if (Character.isWhitespace(c) || c == '=' || c == ';') { - if (isEmpty()) { - throw metaEx("ERROR_InvalidCapabilitySyntax", capName); - } - break; - } else if (!isAlphaNum(c)) { - throw metaEx("ERROR_InvalidCapabilitySyntax", capName); - } - } - String type = cut(1); - - switch (type.toLowerCase(Locale.ENGLISH)) { - case "version": - makeVersion = true; - break; - case "string": - break; - case "long": - case "double": - case "": - default: - throw metaEx("ERROR_UnsupportedCapabilityType", capName, type); - } - skipWhitespaces(); - } - if (c != '=') { // NOI18N - throw metaEx("ERROR_InvalidCapabilitySyntax", capName); - } - String s = parseArgument(); - Object o; - - if (makeVersion) { - try { - o = Version.fromString(s); - } catch (IllegalArgumentException ex) { - throw metaEx("ERROR_InvalidCapabilityVersion", capName, s); - } - } else { - o = s; - } - capabilities.put(capName, o); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoader.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoader.java deleted file mode 100644 index 3a43d773b721..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoader.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.Map; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.SuppressFBWarnings; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * Abstraction that loads metadata for a given component. - * - * @author sdedic - */ -public interface MetadataLoader extends Closeable { - - ComponentInfo getComponentInfo(); - - List getErrors(); - - Archive getArchive() throws IOException; - - /** - * License name/type. Not the actual content, but general name, like "Oracle OTN license", - * "GPLv2" or so. - * - * @return license type or {@code null} - */ - String getLicenseType(); - - /** - * License ID. Usually a digest of the license file contents. - * - * @return license ID - */ - String getLicenseID(); - - /** - * Path to the license file. Should be to iterate through {@link #getArchive} to obtain the - * license contents. - * - * @return path to the license or {@code null} - */ - String getLicensePath(); - - MetadataLoader infoOnly(boolean only); - - boolean isNoVerifySymlinks(); - - void loadPaths() throws IOException; - - Map loadPermissions() throws IOException; - - Map loadSymlinks() throws IOException; - - void setNoVerifySymlinks(boolean noVerifySymlinks); - - /** - * Completes the metadata. The entire file may be loaded in order to load all the metadata. - * - * @throws IOException if the metadata load fails. - * @return ComponentInfo with completed metadata - */ - ComponentInfo completeMetadata() throws IOException; - - default FileDownloader configureRelatedDownloader(FileDownloader dn) { - return dn; - } - - @SuppressWarnings("unused") - default Date isLicenseAccepted(ComponentInfo info, String licenseID) { - return null; - } - - /** - * A provider-dependent way of accepting a license. If the Loader returns {@code true}, it has - * to record the accepted license on its own. Returning {@code false} will suppress the default - * recording. {@code null} means the default recording should be used. - *

- * The default implementation returns {@code null}. - * - * @param info Component for which the license is being accepted. - * @param licenseID ID of the license. - * @param licenseText The text of the license. - * @param d date accepted - * @return recording decision. - * @throws IOException - */ - @SuppressFBWarnings(value = "NP_BOOLEAN_RETURN_NULL", justification = "The return value is a tri-state, indicates a success, denial, or default.") - default Boolean recordLicenseAccepted(ComponentInfo info, String licenseID, String licenseText, Date d) throws IOException { - return null; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoaderAdapter.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoaderAdapter.java deleted file mode 100644 index a839108116ac..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/MetadataLoaderAdapter.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.Map; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.remote.FileDownloader; - -/** - * Delegation adapter, for easier wrapping a MetadataLoader instance. - * - * @author sdedic - */ -public class MetadataLoaderAdapter implements MetadataLoader { - private final MetadataLoader delegate; - - public MetadataLoaderAdapter(MetadataLoader delegate) { - this.delegate = delegate; - } - - @Override - public ComponentInfo getComponentInfo() { - return delegate.getComponentInfo(); - } - - @Override - public List getErrors() { - return delegate.getErrors(); - } - - @Override - public Archive getArchive() throws IOException { - return delegate.getArchive(); - } - - @Override - public String getLicenseType() { - return delegate.getLicenseType(); - } - - @Override - public String getLicenseID() { - return delegate.getLicenseID(); - } - - @Override - public String getLicensePath() { - return delegate.getLicensePath(); - } - - @Override - public MetadataLoader infoOnly(boolean only) { - return delegate.infoOnly(only); - } - - @Override - public boolean isNoVerifySymlinks() { - return delegate.isNoVerifySymlinks(); - } - - @Override - public void loadPaths() throws IOException { - delegate.loadPaths(); - } - - @Override - public Map loadPermissions() throws IOException { - return delegate.loadPermissions(); - } - - @Override - public Map loadSymlinks() throws IOException { - return delegate.loadSymlinks(); - } - - @Override - public void setNoVerifySymlinks(boolean noVerifySymlinks) { - delegate.setNoVerifySymlinks(noVerifySymlinks); - } - - @Override - public ComponentInfo completeMetadata() throws IOException { - return delegate.completeMetadata(); - } - - @Override - public FileDownloader configureRelatedDownloader(FileDownloader dn) { - return delegate.configureRelatedDownloader(dn); - } - - @Override - public Boolean recordLicenseAccepted(ComponentInfo info, String licenseID, String licenseText, Date d) throws IOException { - return delegate.recordLicenseAccepted(info, licenseID, licenseText, d); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public Date isLicenseAccepted(ComponentInfo info, String licenseID) { - return delegate.isLicenseAccepted(info, licenseID); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/SortedProperties.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/SortedProperties.java deleted file mode 100644 index 902dbf9c730d..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/persist/SortedProperties.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.persist; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; - -/** - * Provides sorted properties, for deterministic saves. - */ -public final class SortedProperties extends Properties { - - private static final long serialVersionUID = 1L; - - @Override - @SuppressWarnings({"rawtypes", "unchecked"}) - public Enumeration propertyNames() { - return (Enumeration) keys(); - } - - @Override - @SuppressWarnings({"rawtypes", "unchecked"}) - public synchronized Enumeration keys() { - Enumeration keysEnum = super.keys(); - List keyList = new ArrayList<>(); - while (keysEnum.hasMoreElements()) { - keyList.add((String) keysEnum.nextElement()); - } - Collections.sort(keyList); - return Collections.enumeration((Collection) keyList); - } - - @Override - public Set> entrySet() { - TreeSet> treeSet = new TreeSet<>(Comparator.comparing(o -> ((String) o.getKey()))); - treeSet.addAll(super.entrySet()); - return Collections.synchronizedSet(treeSet); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/Bundle.properties b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/Bundle.properties deleted file mode 100644 index f94b2269d185..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/Bundle.properties +++ /dev/null @@ -1,72 +0,0 @@ -# There's an important trailing space in the next key -MSG_DownloadReceivingBytes=Receiving {0} kB: -# The progress bar should have a frame and exactly 20 space characters -MSG_DownloadProgress@=[ ] -MSG_DownloadProgressSignChar@=# -MSG_DownloadingDone=Done. -MSG_DownloadingDone_Simple@=#DownloadDone -MSG_DownloadingTerminated=Terminated. -MSG_DownloadingTerminated_Simple@=#DownloadTerminated -MSG_Downloading=Downloading: {0} from {1} -MSG_UsingFile=Loading: {0} from local file -MSG_DownloadingVerbose=Downloading: {0} (source: {1}) -MSG_DownloadingFrom=Downloading from: {0} -# {0} file -MSG_Downloading_Simple@=#Download:{0} -MSG_ProgressStart_Simple@=#Size:{0} -MSG_Progress_Simple@=#Received:{0} -MSG_Loaded_Cache=Loaded cache for URL: {0}, stored as: {1} -# {0} - original error message -ERR_ComputeDigest=Error computing digest: {0} -# {0} - expected fingerprint, {1} computed fingerprint -ERR_FileDigestError=Corrupted file, digest does not match. Expected {0}, got {1} - -EXC_ProxyFailed=Failed to connect through proxy: {0} -EXC_TimeoutConnectTo=Timeout while connecting to {0} -EXC_CannotConnectTo=Cannot connect to {0} - -REMOTE_CannotHandleLocation=Unable to handle catalog at {0} - -EXC_InterruptedConnectingTo=Interrupted while connecting to {0} -REBUILD_ErrorCommunicatingImageTool=Error communicating with the image tool: {0} - -# {0} - component prefix -REMOTE_BadComponentVersion=Bad version for component {0} - -REMOTE_IncompatibleComponentVersion=Component {0} does not provide a compatible version. Run with -v to see list of versions. -REMOTE_NoSpecificVersion=Component {0} does not exist in specified version {1} -REMOTE_NoSpecificVersion2=Component {0} does not exist in specified version {1}, pick e.g. {2}. -REMOTE_CannotDeleteLocalFile=Could not delete temporary file {0}: {1} -REMOTE_UnknownComponentId=Component "{0}" is not available in catalog. -REMOTE_UnknownComponentMaybeFile=Component "{0}" is not available in catalog.\n\ - Note: a file {0} exists; to use component stored locally, use -L option \n\ - \tgu -L {0} - -REMOTE_InvalidDownloadURL=Invalid component URL {0}: {1} -REMOTE_InvalidHash=Invalid hash for component {0}: {1} -REMOTE_CatalogLabel=Component catalog -REMOTE_ErrorDownloadCatalogNotFound=The component catalog was not found at {0}. -REMOTE_ErrorDownloadCatalog=Error downloading component catalog from {0}: {1}. \n\ - Please check your connection and proxy settings. \ - If your machine is behind a proxy, set your environment variables (http_proxy, https_proxy, ...) appropriately. -REMOTE_ErrorDownloadCatalogProxy=Component catalog is unreachable. \n\ - Please check your connection and proxy settings. \ - If your machine is behind a proxy, set your environment variables (http_proxy, https_proxy, ...) appropriately. -REMOTE_CorruptedCatalogFile=Catalog file {0} is corrupted. -REMOTE_ComponentFileLabel=Component {1}: {0} -REMOTE_UnsupportedGraalVersion=Unsupported GraalVM version: {0}, platform {1}/{2} -REMOTE_ErrorDownloadingComponent=Error downloading component {0} from {1}: {2} -REMOTE_ErrorDownloadingNotExist=Package for component {0} is not accessible at {1} -REMOTE_UpgradeGraalVMCore=Component {0} requires to upgrade GraalVM Core to at least {1}. -REMOTE_FailedToParseParameter=Failed to parse location parameter: {0} -# {0} - channel label -# {1} - exception message -REMOTE_CannotLoadChannel=Could not load channel {0}: {1} - -# {0} - edition id (i.e. CE, EE). -ERR_NoSuchEdition=Unknown GraalVM edition: {0} - -LICENSE_RemoteLicenseDescription=Downloading license: {0} -ERROR_DownloadLicense=Could not download license {0}: {1} -WARN_HttpProxyGarbage=WARNING: The http_proxy environment variable value may be incorrect: {0} -WARN_HttpsProxyGarbage=WARNING: The https_proxy environment variable value may be incorrect: {0} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/CatalogIterable.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/CatalogIterable.java deleted file mode 100644 index 34a415d2f085..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/CatalogIterable.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.File; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.PathMatcher; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.BundleConstants; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.ComponentIterable; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.FileIterable; -import org.graalvm.component.installer.FileIterable.FileComponent; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.UnknownVersionException; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.DistributionType; -import org.graalvm.component.installer.persist.MetadataLoader; - -/** - * Interprets installer arguments as entries from a catalog. - * - * @author sdedic - */ -public class CatalogIterable implements ComponentIterable { - private final CommandInput input; - private final Feedback feedback; - private ComponentCatalog remoteRegistry; - private boolean verifyJars; - private boolean incompatible; - - public CatalogIterable(CommandInput input, Feedback feedback) { - this.input = input; - this.feedback = feedback.withBundle(CatalogIterable.class); - } - - public boolean isVerifyJars() { - return verifyJars; - } - - @Override - public void setVerifyJars(boolean verifyJars) { - this.verifyJars = verifyJars; - } - - @Override - public Iterator iterator() { - return new It(); - } - - void setRemoteRegistry(ComponentCatalog remote) { - this.remoteRegistry = remote; - } - - ComponentCatalog getRegistry() { - if (remoteRegistry == null) { - remoteRegistry = input.getCatalogFactory().createComponentCatalog(input); - } - return remoteRegistry; - } - - @Override - public ComponentIterable allowIncompatible() { - incompatible = true; - return this; - } - - private Version.Match versionFilter; - - @Override - public ComponentIterable matchVersion(Version.Match m) { - this.versionFilter = m; - return this; - } - - private ComponentParam latest(String s, Collection infos) { - List ordered = new ArrayList<>(infos); - Collections.sort(ordered, ComponentInfo.reverseVersionComparator(input.getLocalRegistry().getManagementStorage())); - boolean progress = input.optValue(Commands.OPTION_NO_DOWNLOAD_PROGRESS) == null; - return createComponentParam(s, ordered.get(0), progress); - } - - private class It implements Iterator { - private void thrownUnknown(String fname, boolean throwUnknown) { - File f = new File(fname); - if (f.exists() && f.isFile()) { - throw feedback.failure("REMOTE_UnknownComponentMaybeFile", null, fname); - } else if (throwUnknown) { - throw feedback.failure("REMOTE_UnknownComponentId", null, fname); - } - } - - @Override - public boolean hasNext() { - return !expandedIds.isEmpty() || input.hasParameter(); - } - - private List expandId(String pattern, Version.Match vm) { - // need to lowercase before passing to glob pattern: on UNIX, glob is case-sensitive, on - // Windows it is not. Lowercase will unify. - PathMatcher pm = FileSystems.getDefault().getPathMatcher("glob:" + pattern.toLowerCase(Locale.ENGLISH)); // NOI18N - Set ids = new HashSet<>(getRegistry().getComponentIDs()); - Map abbreviatedIds = new HashMap<>(); - for (String id : ids) { - Collection infos = getRegistry().loadComponents(id, Version.NO_VERSION.match(Version.Match.Type.GREATER), false); - for (ComponentInfo info : infos) { - abbreviatedIds.put(info, getRegistry().shortenComponentId(info)); - } - } - - // merge full IDs with unambiguous abbreviations. - ids.addAll(abbreviatedIds.values()); - if (ids.contains(pattern)) { - // no wildcards, apparently - return Collections.singletonList(pattern); - } - for (Iterator it = ids.iterator(); it.hasNext();) { - String s = it.next().toLowerCase(Locale.ENGLISH); - if (!pm.matches(SystemUtils.fromUserString(s))) { - it.remove(); - } - } - // translate back to components, to merge abbreviations and full Ids. - Set infos = new HashSet<>(); - ids.forEach(s -> infos.add(getRegistry().findComponent(s, vm))); - List sorted = new ArrayList<>(); - for (ComponentInfo ci : infos) { - if (ci == null) { - continue; - } - String ab = abbreviatedIds.get(ci); - if (pm.matches(SystemUtils.fromUserString(ab))) { - sorted.add(ab); - } else { - sorted.add(ci.getId()); - } - } - Collections.sort(sorted); - return sorted; - } - - /** - * The command line parameters expanded from wildcards. - */ - private final List expandedIds = new ArrayList<>(); - - @Override - public ComponentParam next() { - if (!expandedIds.isEmpty()) { - return processParameter(expandedIds.remove(0)); - } - String s = input.nextParameter(); - Version.Match[] m = new Version.Match[1]; - String id = Version.idAndVersion(s, m); - if (m[0].getType() == Version.Match.Type.MOSTRECENT && versionFilter != null) { - m[0] = versionFilter; - } - List expanded = expandId(id, m[0]); - if (expanded.isEmpty()) { - // just process it ;) - return processParameter(s); - } - String suffix = s.substring(id.length()); - for (String ei : expanded) { - expandedIds.add(ei + suffix); - } - return processParameter(expandedIds.remove(0)); - } - - private ComponentParam processParameter(String s) { - ComponentInfo info; - try { - Version.Match[] m = new Version.Match[1]; - String id = Version.idAndVersion(s, m); - if (m[0].getType() == Version.Match.Type.MOSTRECENT && versionFilter != null) { - m[0] = versionFilter; - } - try { - info = getRegistry().findComponent(id, m[0]); - } catch (UnknownVersionException ex) { - // could not find anything to match the user version against - if (ex.getCandidate() == null) { - throw feedback.failure("REMOTE_NoSpecificVersion", ex, id, m[0].getVersion().displayString()); - } else { - throw feedback.failure("REMOTE_NoSpecificVersion2", ex, id, m[0].getVersion().displayString(), ex.getCandidate().displayString()); - } - } - if (info == null) { - // must be already initialized - ComponentInfo localInfo = input.getLocalRegistry().findComponent(id, m[0]); - if (localInfo != null && localInfo.getDistributionType() == DistributionType.BUNDLED) { - // bundled components are pre-installed and do not need to be downloaded - return createComponentParam(s, localInfo, false); - } - Version gv = input.getLocalRegistry().getGraalVersion(); - Version.Match selector = gv.match(Version.Match.Type.INSTALLABLE); - Collection infos = getRegistry().loadComponents(id, selector, false); - if (infos != null && !infos.isEmpty()) { - if (incompatible) { - return latest(s, infos); - } - String rvs = infos.iterator().next().getRequiredGraalValues().get(BundleConstants.GRAAL_VERSION); - Version rv = Version.fromString(rvs); - if (rv.compareTo(gv) > 0) { - throw feedback.failure("REMOTE_UpgradeGraalVMCore", null, id, rvs); - } - if (m[0].getType() == Version.Match.Type.EXACT) { - throw feedback.failure("REMOTE_NoSpecificVersion", null, id, m[0].getVersion().displayString()); - } - } - // last try, catch obsolete components: - infos = getRegistry().loadComponents(id, Version.NO_VERSION.match(Version.Match.Type.GREATER), false); - if (infos != null && !infos.isEmpty()) { - if (incompatible) { - return latest(s, infos); - } - throw feedback.failure("REMOTE_IncompatibleComponentVersion", null, id); - } - thrownUnknown(s, true); - } - } catch (FailedOperationException ex) { - thrownUnknown(s, false); - throw ex; - } - boolean progress = input.optValue(Commands.OPTION_NO_DOWNLOAD_PROGRESS) == null; - return createComponentParam(s, info, progress); - } - } - - @Override - public ComponentParam createParam(String cmdString, ComponentInfo info) { - boolean progress = input.optValue(Commands.OPTION_NO_DOWNLOAD_PROGRESS) == null; - return createComponentParam(cmdString, info, progress); - } - - protected ComponentParam createComponentParam(String cmdLineString, ComponentInfo info, boolean progress) { - RemoteComponentParam param = new CatalogItemParam( - getRegistry().getDownloadInterceptor(), - info, - info.getName(), - cmdLineString, - feedback, progress); - param.setVerifyJars(verifyJars); - return param; - } - - public static class CatalogItemParam extends RemoteComponentParam { - final ComponentCatalog.DownloadInterceptor configurer; - - public CatalogItemParam(ComponentCatalog.DownloadInterceptor conf, ComponentInfo catalogInfo, String dispName, String spec, Feedback feedback, boolean progress) { - super(catalogInfo, dispName, spec, feedback, progress); - this.configurer = conf; - } - - @Override - public MetadataLoader createMetaLoader() throws IOException { - if (configurer == null) { - return super.createMetaLoader(); - } else { - return configurer.interceptMetadataLoader(getCatalogInfo(), super.createMetaLoader()); - } - } - - @Override - public FileDownloader configureRelatedDownloader(FileDownloader dn) { - return configurer.processDownloader(getCatalogInfo(), dn); - } - - @Override - protected FileDownloader createDownloader() { - FileDownloader d = super.createDownloader(); - return configureRelatedDownloader(d); - } - - @Override - protected MetadataLoader metadataFromLocal(Path localFile) throws IOException { - String serial = getCatalogInfo().getTag(); - FileDownloader theDownloader = getDownloader(); - if (serial == null || "".equals(serial)) { - serial = theDownloader != null ? SystemUtils.fingerPrint(theDownloader.getReceivedDigest(), false) : null; - } - FileComponent fc = new FileIterable.FileComponent(localFile.toFile(), isVerifyJars(), serial, getFeedback()); - return fc.createFileLoader(); - } - - @Override - public ComponentInfo completeMetadata() throws IOException { - return createFileLoader().completeMetadata(); - } - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/FileDownloader.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/FileDownloader.java deleted file mode 100644 index e114c46da45e..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/FileDownloader.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.URLConnectionFactory; -import java.util.Collections; -import java.util.List; - -/** - * Downloads file to local, optionally checks its integrity using digest. - * - * @author sdedic - */ -public final class FileDownloader { - private static final int TRANSFER_LENGTH = 2048; - private static final long MIN_PROGRESS_THRESHOLD = Long.getLong("org.graalvm.component.installer.minDownloadFeedback", 1024 * 1024); - private final String fileDescription; - private final URL sourceURL; - private final Feedback feedback; - - private File downloadDir; - private File localFile; - private long size; - private static boolean deleteTemporary = !Boolean.FALSE.toString().equals(System.getProperty("org.graalvm.component.installer.deleteTemporary")); - private boolean verbose; - private static volatile File tempDir; - private boolean displayProgress; - private byte[] shaDigest; - long sizeThreshold = MIN_PROGRESS_THRESHOLD; - private final Map requestHeaders = new HashMap<>(); - private Consumer dataInterceptor; - private URLConnectionFactory connectionFactory; - private boolean simpleOutput; - - private Map> responseHeader = Collections.emptyMap(); - private DownloadExceptionInterceptor downloadExceptionInterceptor = (ex, fd) -> ex; - - public interface DownloadExceptionInterceptor { - /** - * When null is returned another connection will be attempted. Otherwise the returned - * Exception is thrown. - */ - IOException interceptDownloadException(IOException downloadException, FileDownloader fileDownloader); - } - - public Map> getResponseHeader() { - return responseHeader; - } - - public Map getRequestHeaders() { - return Collections.unmodifiableMap(requestHeaders); - } - - /** - * Will intercept possible connection problem, if null is returned the downloader will do - * another attempt to download otherwise the returned Exception is thrown. - * - * @param downloadExceptionInterceptor - */ - public void setDownloadExceptionInterceptor(DownloadExceptionInterceptor downloadExceptionInterceptor) { - if (downloadExceptionInterceptor != null) { - this.downloadExceptionInterceptor = downloadExceptionInterceptor; - } - } - - /** - * Algorithm to compute file digest. By default SHA-256 is used. - */ - private String digestAlgorithm = "SHA-256"; - - public FileDownloader(String fileDescription, URL sourceURL, Feedback feedback) { - this.fileDescription = fileDescription; - this.sourceURL = sourceURL; - this.feedback = feedback.withBundle(FileDownloader.class); - } - - public void setShaDigest(byte[] shaDigest) { - this.shaDigest = shaDigest; - } - - public File getDownloadDir() { - return downloadDir; - } - - public void setDownloadDir(File downloadDir) { - this.downloadDir = downloadDir; - } - - public static void setDeleteTemporary(boolean deleteTemporary) { - FileDownloader.deleteTemporary = deleteTemporary; - } - - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } - - public void setDisplayProgress(boolean displayProgress) { - this.displayProgress = displayProgress; - } - - public void addRequestHeader(String header, String val) { - requestHeaders.put(header, val); - } - - public String getDigestAlgorithm() { - return digestAlgorithm; - } - - public void setDigestAlgorithm(String digestAlgorithm) { - this.digestAlgorithm = digestAlgorithm; - } - - public static synchronized File createTempDir() throws IOException { - if (tempDir == null) { - Path p = Files.createTempDirectory("graalvm_install"); // NOI18N - tempDir = p.toFile(); - tempDir.deleteOnExit(); - } - return tempDir; - } - - private static File deleteOnExit(File f) { - if (deleteTemporary) { - f.deleteOnExit(); - } - return f; - } - - public String getFileDescription() { - return fileDescription; - } - - public URL getSourceURL() { - return sourceURL; - } - - private static int toKB(long size) { - return (int) (size + 1023) / 1024; - } - - StringBuilder progressString; - String backspaceString; - int startPos; - int signCount; - long received; - char signChar; - MessageDigest fileDigest; - byte[] receivedDigest; - - public File getLocalFile() { - return localFile; - } - - void setupProgress() { - if (simpleOutput) { - feedback.output("MSG_ProgressStart_Simple@", Long.toString(size)); - return; - } - if (!displayProgress) { - return; - } - progressString = new StringBuilder(feedback.l10n("MSG_DownloadProgress@")); // NOI18N - signChar = feedback.l10n("MSG_DownloadProgressSignChar@").charAt(0); // NOI18N - startPos = progressString.toString().indexOf(' '); - StringBuilder bs = new StringBuilder(progressString.length()); - for (int i = 0; i < progressString.length(); i++) { - bs.append('\b'); // NOI18N - } - backspaceString = bs.toString(); - } - - int cnt(long rcvd) { - return (int) ((rcvd * 20 + (rcvd / 2)) / size); - } - - void makeProgress(boolean first, int chunk) { - if (!displayProgress) { - return; - } - int now = cnt(received); - received += chunk; - int next = cnt(received); - if (now < next) { - if (simpleOutput) { - feedback.output("MSG_Progress_Simple@", Long.toString(received)); - return; - } - progressString.setCharAt(next + startPos - 1, signChar); - signCount = next; - - if (!first) { - feedback.verbatimPart(backspaceString, false); - } - feedback.verbatimPart(progressString.toString(), false); - } - } - - void stopProgress(boolean success) { - if (displayProgress && !simpleOutput) { - feedback.verbatimPart(backspaceString, false); - } - String simpleSuffix = simpleOutput ? "_Simple@" : ""; - if (success) { - feedback.verboseOutput("MSG_DownloadingDone" + simpleSuffix); - } else { - feedback.output("MSG_DownloadingTerminated" + simpleSuffix); - } - } - - void updateFileDigest(ByteBuffer input) throws IOException { - if (shaDigest == null) { - return; - } - if (fileDigest == null) { - try { - fileDigest = MessageDigest.getInstance(getDigestAlgorithm()); // NOI18N - } catch (NoSuchAlgorithmException ex) { - throw new IOException( - feedback.l10n("ERR_ComputeDigest", ex.getLocalizedMessage()), - ex); - } - } - fileDigest.update(input); - } - - static String fingerPrint(byte[] digest) { - return SystemUtils.fingerPrint(digest); - } - - byte[] getDigest() { - return fileDigest.digest(); - } - - public byte[] getReceivedDigest() throws IOException { - if (receivedDigest == null) { - if (localFile == null) { - return null; - } - receivedDigest = SystemUtils.computeFileDigest(localFile.toPath(), getDigestAlgorithm()); - } - return receivedDigest == null ? null : receivedDigest.clone(); - } - - void verifyDigest() throws IOException { - if (shaDigest == null || /* for testing */ shaDigest.length == 0) { - return; - } - byte[] computed = fileDigest.digest(); - this.receivedDigest = computed; - if (Arrays.equals(computed, shaDigest)) { - return; - } - throw new IOException(feedback.l10n("ERR_FileDigestError", - fingerPrint(shaDigest), fingerPrint(computed))); - } - - void configureHeaders(URLConnection con) { - for (String h : requestHeaders.keySet()) { - con.addRequestProperty(h, requestHeaders.get(h)); - } - } - - protected void dataDownloaded(SeekableByteChannel ch) { - if (dataInterceptor != null) { - dataInterceptor.accept(ch); - } - } - - public FileDownloader setDataInterceptor(Consumer interceptor) { - this.dataInterceptor = interceptor; - return this; - } - - private void copySubtree(Path from) throws IOException { - Path to = Files.createTempDirectory(createTempDir().toPath(), "download"); - SystemUtils.copySubtree(from, to); - localFile = to.toFile(); - } - - private int attempt; - - public int getAttemptNr() { - return attempt; - } - - public void download() throws IOException { - Path localCache = feedback.getLocalCache(sourceURL); - if (localCache != null) { - feedback.verboseOutput("MSG_Loaded_Cache", sourceURL, localCache); - localFile = localCache.toFile(); - Map> respCache = feedback.getLocalResponseHeadersCache(sourceURL); - responseHeader = respCache == null ? Collections.emptyMap() : respCache; - return; - } - - simpleOutput = Boolean.TRUE.toString().equals(System.getProperty(CommonConstants.SYSPROP_SIMPLE_OUTPUT)); - boolean fromFile = sourceURL.getProtocol().equals("file"); - if (simpleOutput) { - feedback.output( - "MSG_Downloading_Simple@", - getSourceURL(), getFileDescription() == null ? "" : getFileDescription()); - } else { - if (fileDescription != null) { - if (!feedback.verboseOutput("MSG_DownloadingVerbose", getFileDescription(), getSourceURL())) { - feedback.output(fromFile ? "MSG_UsingFile" : "MSG_Downloading", getFileDescription(), getSourceURL().getHost()); - } - } else { - feedback.output("MSG_DownloadingFrom", getSourceURL()); - } - } - - if (fromFile) { - try { - Path p = Paths.get(sourceURL.toURI()); - if (Files.isDirectory(p)) { - copySubtree(p); - return; - } - } catch (URISyntaxException ex) { - throw new IOException(ex); - } - } - - URLConnectionFactory urlFactory = getConnectionFactory(); - URLConnection conn = null; - attempt = 0; - do { - try { - attempt++; - conn = urlFactory.createConnection(sourceURL, this::configureHeaders); - } catch (IOException ex) { - if ((ex = downloadExceptionInterceptor.interceptDownloadException(ex, this)) != null) { - throw ex; - } - } - } while (conn == null); - - size = conn.getContentLengthLong(); - if (simpleOutput) { - verbose = feedback.verboseOutput(null); - } else { - verbose = feedback.verbosePart("MSG_DownloadReceivingBytes", toKB(size)); - } - if (verbose) { - displayProgress = true; - } - if (size < sizeThreshold) { - displayProgress = false; - } - - setupProgress(); - ByteBuffer bb = ByteBuffer.allocate(TRANSFER_LENGTH); - localFile = deleteOnExit(File.createTempFile("download", "", downloadDir == null ? createTempDir() : downloadDir)); // NOI18N - boolean first = displayProgress; - boolean success = false; - try ( - ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream()); - SeekableByteChannel wbc = Files.newByteChannel(localFile.toPath(), - StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { - int read; - while ((read = rbc.read(bb)) >= 0) { - if (first && !simpleOutput) { - feedback.verbatimPart(progressString.toString(), false); - } - bb.flip(); - while (bb.hasRemaining()) { - wbc.write(bb); - long pos = wbc.position(); - dataDownloaded(wbc); - wbc.position(pos); - } - bb.flip(); - updateFileDigest(bb); - makeProgress(first, read); - bb.clear(); - first = false; - } - success = true; - } catch (UncheckedIOException ex) { - throw ex.getCause(); - } catch (IOException ex) { - // f.delete(); - throw ex; - } finally { - stopProgress(success); - } - verifyDigest(); - responseHeader = conn.getHeaderFields(); - feedback.addLocalFileCache(sourceURL, localFile.toPath()); - feedback.addLocalResponseHeadersCache(sourceURL, responseHeader); - } - - public void setConnectionFactory(URLConnectionFactory connFactory) { - this.connectionFactory = connFactory; - } - - URLConnectionFactory getConnectionFactory() { - if (connectionFactory == null) { - connectionFactory = new ProxyConnectionFactory(feedback, sourceURL); - } - return connectionFactory; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/GraalEditionList.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/GraalEditionList.java deleted file mode 100644 index 0a11418c8719..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/GraalEditionList.java +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.CommandInput.CatalogFactory; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.GraalEdition; -import org.graalvm.component.installer.persist.DirectoryStorage; - -/** - * The class parses catalog definitions and builds a {@link GraalEdition} list of available - * editions. It also serves as a factory for eventual lists for 'foreign graals' in different - * directories at the same time. - *

- * For compatibility reasons it loads from various sources with with precedence as follows: - *

    - *
  1. {@link #overrideCatalogSpec}, which should be set from {@code -C} or GRAALVM_CATALOG_URL - * environment variable by installer launcher. - *
  2. catalog related properties from the release file; each software sources has a URL - * (mandatory), label and potentially parameters. - *
  3. component_catalog property, which defines all the software sources in a single property - *
- * The edition with empty ({@code ""}) id, the edition whose id matches - * {@link CommonConstants#CAP_EDITION} from the release file (see {@link DirectoryStorage} for how - * the defaults are computed) or the first edition found is the default one: its software - * sources will be used to load the catalogs, unless overriden by a command switch. - * - * @author sdedic - */ -public final class GraalEditionList implements CatalogFactory { - static final String CAP_CATALOG_URL_SUFFIX = "_" + CommonConstants.CAP_CATALOG_URL; // NOI18N - - private final CommandInput input; - private final ComponentRegistry targetGraal; - private final Feedback feedback; - - /** - * Editions, the default should be listed first. - */ - private final List editions = new ArrayList<>(); - - /** - * Map ID > edition. - */ - private final Map editionMap = new HashMap<>(); - - /** - * Cache of foreign GraalVM edition definitions. Note there is not identity-consistency between - * foreign's foreign pointing back to this installation. - */ - private final Map foreignGraals = new HashMap<>(); - - /** - * Hand-override, takes precedence over everything. - */ - private String overrideCatalogSpec; - - /** - * Default single-property definition, read from the release file. Lower priority than separated - * release file properties. - */ - private String defaultCatalogSpec; - - private GraalEdition defaultEdition; - - private boolean remoteSourcesAllowed = true; - - private List localSources = new ArrayList<>(); - - /** - * Compares property keys so that software sources can be ordered. It tries to numeric-order - * according to the substring after {@code component_catalog_} prefix ( - * {@link CommonConstants#CAP_CATALOG_PREFIX}; strings having lower precedence than any any - * number. Two nonnumeric strings are compared alphabetically. - */ - private static final Comparator CHANNEL_KEY_COMPARATOR = new Comparator<>() { - @Override - public int compare(String o1, String o2) { - int i1 = Integer.MAX_VALUE; - int i2 = Integer.MAX_VALUE; - - String k1 = o1.substring(CommonConstants.CAP_CATALOG_PREFIX.length() - 1); - String k2 = o2.substring(CommonConstants.CAP_CATALOG_PREFIX.length() - 1); - if (k1.equals("")) { - i1 = 0; - } else { - if (k1.startsWith("_")) { - k1 = k1.substring(1); - } - try { - i1 = Integer.parseInt(k1); - } catch (NumberFormatException ex) { - } - } - if (k2.equals("")) { - i2 = 0; - } else { - if (k2.startsWith("_")) { - k2 = k2.substring(1); - } - try { - i2 = Integer.parseInt(k2); - } catch (NumberFormatException ex) { - } - } - if (i1 != i2) { - return i1 - i2; - } - return k1.compareToIgnoreCase(k2); - } - }; - - public GraalEditionList(Feedback feedback, CommandInput input, ComponentRegistry reg) { - this.input = input; - this.targetGraal = reg; - this.feedback = feedback.withBundle(GraalEditionList.class); - } - - public String getOverrideCatalogSpec() { - return overrideCatalogSpec; - } - - public void setOverrideCatalogSpec(String overrideCatalogSpec) { - this.overrideCatalogSpec = overrideCatalogSpec; - } - - public String getDefaultCatalogSpec() { - return defaultCatalogSpec; - } - - public void setDefaultCatalogSpec(String defaultCatalogSpec) { - this.defaultCatalogSpec = defaultCatalogSpec; - } - - /** - * Returns the default GraalVM edition. - * - * @return default edition. - */ - public GraalEdition getDefaultEdition() { - init(); - return defaultEdition; - } - - public void setDefaultEdition(GraalEdition ed) { - this.defaultEdition = ed; - } - - /** - * Lists all editions. - * - * @return list of editions, the default one first. - */ - public List editions() { - init(); - return editions; - } - - /** - * Gets an edition with the specified ID. Throws an exception, if that edition does not exist. - * - * @param id edition id. "" or null means default edition. - * @return edition instance - * @throws FailedOperationException if no such edition is configured. - */ - public GraalEdition getEdition(String id) { - if (id == null || "".equals(id)) { - return getDefaultEdition(); - } else { - init(); - GraalEdition e = editionMap.get(id.toLowerCase(Locale.ENGLISH)); - if (e == null) { - throw feedback.failure("ERR_NoSuchEdition", null, id); - } - return e; - } - } - - @SuppressWarnings("ThrowableResultIgnored") - List parseChannelSources(String edId, String overrideSpec) { - List sources = new ArrayList<>(); - if (!remoteSourcesAllowed || overrideSpec == null) { - return sources; - } - int priority = 1; - String[] parts = overrideSpec.split("\\|"); // NOI18N - String id = edId; - if (id == null) { - id = targetGraal.getGraalCapabilities().get(CommonConstants.CAP_EDITION); - } - for (String s : parts) { - SoftwareChannelSource chs = new SoftwareChannelSource(s); - chs.setPriority(priority); - chs.setParameter("edition", id); - sources.add(chs); - priority++; - } - return sources; - } - - void parseSimpleSpecification(String defId, String spec) { - if (spec == null) { - return; - } - String[] eds = spec.split("\\{"); - for (String part : eds) { - if ("".equals(part)) { - continue; - } - String edName; - String edId; - - String src = part; - int endBracket = part.indexOf('}'); - if (endBracket != -1) { - int eqSign = part.indexOf('='); - if (eqSign == -1 || eqSign >= endBracket) { - edId = edName = part.substring(0, endBracket); - } else { - edId = part.substring(0, eqSign); - edName = part.substring(eqSign + 1, endBracket); - } - src = part.substring(endBracket + 1).trim(); - if (src.endsWith("|")) { - src = src.substring(0, src.length() - 1); - } - } else { - edId = defId != null ? defId : "ce"; - edName = getEditionLabel(edId); - if (edName == null) { - edName = getEditionLabel(null); - } - } - GraalEdition ge = new GraalEdition(edId, edName); - boolean def = false; - ge.setSoftwareSources(parseChannelSources(edId, src)); - if (defaultEdition == null && endBracket == -1) { - def = true; - } else if (edId.equals(defId)) { - def = true; - } - registerEdition(ge, def); - } - } - - /** - * @return true, if an explicit override is present. - */ - boolean isExplicitOverride() { - return overrideCatalogSpec != null; - } - - void init() { - if (defaultEdition != null) { - return; - } - String defEditionId = targetGraal.getGraalCapabilities().get(CommonConstants.CAP_EDITION); - - if (isExplicitOverride()) { - initSimple(defEditionId, overrideCatalogSpec); - return; - } - List srcs = readChannelSources(defEditionId); - if (srcs.isEmpty()) { - // no source channels defined for the editionId - srcs = readChannelSources(null); - } - - if (srcs.isEmpty()) { - initSimple(defEditionId, defaultCatalogSpec); - return; - } - List edList = listEditionsFromRelease(); - String label; - List sources; - - if (edList.contains(defEditionId)) { - edList.remove(defEditionId); - label = getEditionLabel(defEditionId); - sources = readChannelSources(defEditionId); - } else if (!edList.remove("")) { - throw new IllegalStateException("Malformed release file."); - } else { - label = getEditionLabel(null); - sources = readChannelSources(null); - } - GraalEdition ge = new GraalEdition(defEditionId, label); - ge.setSoftwareSources(sources); - registerEdition(ge, true); - for (String id : edList) { - label = getEditionLabel(id); - sources = readChannelSources(id); - ge = new GraalEdition(id, label); - ge.setSoftwareSources(sources); - - registerEdition(ge, false); - } - } - - private void registerEdition(GraalEdition ge, boolean defaultEd) { - if (!editions.contains(ge)) { - editions.add(ge); - } - if (defaultEd) { - editionMap.put("", ge); - defaultEdition = ge; - } - editionMap.put(ge.getId().toLowerCase(Locale.ENGLISH), ge); - } - - /** - * Regexp to select individual edition's properties from the release file. The property must - * start with the edition id, separated by {@code "_"}) from the normal property prefix ( - * {@code component_catalog_}), followed by individual attributes of the software source - * definition. Since URL is the only mandatory attribute, the regexp looks for that. - */ - private static final String EDITION_MATCH_REGEXP = "(?:([^_]+)_)?component_catalog(_?.*)_url"; // NOI18N - - private List listEditionsFromRelease() { - Map editionOrder = new HashMap<>(); - addEditions( - editionOrder, - targetGraal.getGraalCapabilities(), - Pattern.compile(EDITION_MATCH_REGEXP)); - addEditions( - editionOrder, - lowercaseMap(input.parameters(false)), - Pattern.compile(CommonConstants.ENV_CATALOG_PREFIX.toLowerCase(Locale.ENGLISH) + EDITION_MATCH_REGEXP)); - List editionIds = new ArrayList<>(editionOrder.keySet()); - Collections.sort(editionIds, (a, b) -> CHANNEL_KEY_COMPARATOR.compare(editionOrder.get(a), editionOrder.get(b))); - return editionIds; - } - - private static void addEditions(Map eds, Map params, Pattern match) { - for (String k : params.keySet()) { - Matcher m = match.matcher(k); - if (m.matches()) { - String id = m.group(1); - if (null == id) { - id = ""; // NOI18N - } - eds.putIfAbsent(id, k); - } - } - } - - private void ensureDefaultDefined(String defEditionId) { - GraalEdition ge; - if (editions.isEmpty()) { - String label = getEditionLabel(defEditionId); - ge = new GraalEdition(defEditionId == null ? "" : defEditionId, label); - } else if (defaultEdition == null) { - ge = editions.get(0); - } else { - ge = defaultEdition; - } - registerEdition(ge, true); - } - - /** - * Performs single-property initialization. - * - * @param defEditionId default edition's ID, as it appears (or defaults) in the release file. - * @param spec specification string. - */ - private void initSimple(String defEditionId, String spec) { - parseSimpleSpecification(defEditionId, spec); - if (editions.isEmpty()) { - String label = getEditionLabel(defEditionId); - GraalEdition ge = new GraalEdition(defEditionId, label); - defaultEdition = ge; - editions.add(ge); - } - foreignGraals.put(targetGraal, this); - ensureDefaultDefined(defEditionId); - } - - String getEditionLabel(String id) { - String readPrefix = id == null ? "" : id + "_"; - String key = readPrefix + CommonConstants.CAP_CATALOG_PREFIX + "editionLabel"; - String label = input.getParameter(CommonConstants.ENV_VARIABLE_PREFIX + key.toUpperCase(Locale.ENGLISH), false); - if (label == null) { - label = targetGraal.getGraalCapabilities().get(key); - } - if (label == null) { - label = targetGraal.getGraalCapabilities().get(CommonConstants.CAP_EDITION); - if (label == null) { - if ("".equals(id) || id == null) { - return "CE"; // NOI18N - } else { - return id.toUpperCase(Locale.ENGLISH); - } - } else { - return label.toUpperCase(Locale.ENGLISH); - } - } - return label; - } - - public boolean isRemoteSourcesAllowed() { - return remoteSourcesAllowed; - } - - public void setRemoteSourcesAllowed(boolean remoteSourcesAllowed) { - this.remoteSourcesAllowed = remoteSourcesAllowed; - } - - private static Map lowercaseMap(Map map) { - Map res = new HashMap<>(); - for (String s : map.keySet()) { - res.put(s.toLowerCase(Locale.ENGLISH), map.get(s)); - } - return res; - } - - List readChannelSources(String editionPrefix) { - List res; - String readPrefix = editionPrefix == null ? "" : editionPrefix + "_"; - Map lcEnv = lowercaseMap(input.parameters(false)); - res = readChannelSources(editionPrefix, CommonConstants.ENV_VARIABLE_PREFIX.toLowerCase(Locale.ENGLISH) + readPrefix, lcEnv); - if (res != null && !res.isEmpty()) { - return res; - } - if (remoteSourcesAllowed) { - return readChannelSources(editionPrefix, readPrefix, input.getLocalRegistry().getGraalCapabilities()); // NOI18N - } else { - List l = new ArrayList<>(); - return l; - } - } - - List readChannelSources(String id, String pref, Map graalCaps) { - List sources = new ArrayList<>(); - if (!remoteSourcesAllowed) { - return sources; - } - String prefix = pref + CommonConstants.CAP_CATALOG_PREFIX; - List orderedKeys = graalCaps.keySet().stream().filter((k) -> { - String lk = k.toLowerCase(Locale.ENGLISH); - return lk.startsWith(prefix) && lk.endsWith(CAP_CATALOG_URL_SUFFIX); - }).map((k) -> k.substring(0, k.length() - CAP_CATALOG_URL_SUFFIX.length())).collect(Collectors.toList()); - Collections.sort(orderedKeys, CHANNEL_KEY_COMPARATOR); - - int priority = 0; - for (String key : orderedKeys) { - String url = graalCaps.get(key + CAP_CATALOG_URL_SUFFIX); - String lab = graalCaps.get(key + "_" + CommonConstants.CAP_CATALOG_LABEL); - if (url == null) { - continue; - } - SoftwareChannelSource s = new SoftwareChannelSource(url, lab); - s.setPriority(priority); - for (String a : graalCaps.keySet()) { - if (!(a.startsWith(key) && a.length() > key.length() + 1)) { - continue; - } - String k = a.substring(key.length() + 1).toLowerCase(Locale.ENGLISH); - switch (k) { - case CommonConstants.CAP_CATALOG_LABEL: - case CommonConstants.CAP_CATALOG_URL: - continue; - } - s.setParameter(k, graalCaps.get(a)); - } - if (s.getParameter("edition") == null) { - s.setParameter("edition", id != null ? id : targetGraal.getGraalCapabilities().get(CommonConstants.CAP_EDITION)); - } - - sources.add(s); - priority++; - } - return sources; - } - - RemoteCatalogDownloader createEditionDownloader(GraalEdition edition) { - GraalEdition ed = edition; - if (ed == null) { - ed = defaultEdition; - } - RemoteCatalogDownloader dn = new RemoteCatalogDownloader(input, feedback, overrideCatalogSpec); - Stream.concat(ed.getSoftwareSources().stream(), localSources.stream()).forEach(dn::addLocalChannelSource); - // FIXME: temporary hack, remember to cleanup RemoteCatalogDownloader from debris, most of - // functionality - // has moved here. - dn.setRemoteSourcesAllowed(false); - return dn; - } - - public void addLocalChannelSource(SoftwareChannelSource src) { - src.setParameter("reportErrors", Boolean.FALSE.toString()); - localSources.add(src); - } - - final class GE extends GraalEdition { - GE(String id, String displayName) { - super(id, displayName); - } - - @Override - public SoftwareChannel getCatalogProvider() { - SoftwareChannel ch = super.getCatalogProvider(); - if (ch == null) { - ch = createEditionDownloader(this); - setCatalogProvider(ch); - } - return ch; - } - } - - GraalEditionList listGraalEditions(CommandInput in, ComponentRegistry otherGraal) { - return foreignGraals.computeIfAbsent(otherGraal, (og) -> { - GraalEditionList gl = new GraalEditionList(feedback, in, og); - gl.setRemoteSourcesAllowed(remoteSourcesAllowed); - String defCatalog = og.getGraalCapabilities().get(CommonConstants.RELEASE_CATALOG_KEY); - gl.setDefaultCatalogSpec(defCatalog); - return gl; - }); - } - - /** - * Cached instance of catalog, the storage tracks origin of supplied ComponentInfos. - */ - private ComponentCatalog catalog; - - @Override - public ComponentCatalog createComponentCatalog(CommandInput in) { - ComponentRegistry targetGraalVM = in.getLocalRegistry(); - if (targetGraalVM != this.targetGraal) { - GraalEditionList gl = listGraalEditions(in, targetGraalVM); - return gl.createComponentCatalog(in); - } - if (catalog != null) { - return catalog; - } - String edId = in.optValue(Commands.OPTION_USE_EDITION, ""); - GraalEdition ge = getEdition(edId); - RemoteCatalogDownloader downloader = createEditionDownloader(ge); - CatalogContents col = new CatalogContents(feedback, downloader.getStorage(), targetGraalVM); - return catalog = col; - } - - @Override - public List listEditions(ComponentRegistry targetGraalVM) { - return editions(); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/MergeStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/MergeStorage.java deleted file mode 100644 index 0ba1a49cfe8c..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/MergeStorage.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.graalvm.component.installer.ComponentCatalog; -import org.graalvm.component.installer.FailedOperationException; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.IncompatibleException; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.persist.AbstractCatalogStorage; -import org.graalvm.component.installer.persist.MetadataLoader; - -/** - * The Storage merges storages of individual providers. - * - * @author sdedic - */ -public class MergeStorage extends AbstractCatalogStorage implements ComponentCatalog.DownloadInterceptor { - private final Map channelMap = new HashMap<>(); - private final List channels = new ArrayList<>(); - private final Map channelInfos = new HashMap<>(); - - private boolean ignoreCatalogErrors; - private boolean acceptAllSources = true; - - public MergeStorage(ComponentRegistry localRegistry, Feedback feedback) { - super(localRegistry, feedback, null); - } - - public boolean isAcceptAllSources() { - return acceptAllSources; - } - - public void setAcceptAllSources(boolean acceptAllSources) { - this.acceptAllSources = acceptAllSources; - } - - public void addChannel(SoftwareChannelSource info, SoftwareChannel delegate) { - channels.add(delegate); - channelInfos.put(delegate, info); - } - - public boolean isIgnoreCatalogErrors() { - return ignoreCatalogErrors; - } - - public void setIgnoreCatalogErrors(boolean ignoreCatalogErrors) { - this.ignoreCatalogErrors = ignoreCatalogErrors; - } - - private void reportError(Exception exc, SoftwareChannel errChannel) { - if (exc == null) { - return; - } - // the previous error is overwritten, so at least report it before it is - // forgot: - SoftwareChannelSource info = channelInfos.get(errChannel); - String l = info.getLabel(); - if (l == null) { - l = info.getLocationURL(); - } - feedback.error("REMOTE_CannotLoadChannel", exc, l, exc.getLocalizedMessage()); - } - - private boolean idsLoaded; - - @Override - public Set listComponentIDs() throws IOException { - Set ids = new HashSet<>(); - List savedEx = new ArrayList<>(); - List errChannels = new ArrayList<>(); - boolean oneSucceeded = false; - Exception toThrow = null; - for (SoftwareChannel del : new ArrayList<>(channels)) { - try { - ids.addAll(del.getStorage().listComponentIDs()); - oneSucceeded = true; - } catch (IncompatibleException ex) { - savedEx.add(ex); - errChannels.add(del); - channels.remove(del); - } catch (IOException | FailedOperationException ex) { - if (!isIgnoreCatalogErrors()) { - throw ex; - } - if (!idsLoaded) { - reportError(ex, del); - } - toThrow = ex; - channels.remove(del); - } - } - if (!oneSucceeded || ids.isEmpty()) { - for (int i = 0; i < savedEx.size(); i++) { - reportError(toThrow = savedEx.get(i), errChannels.get(i)); - } - if (toThrow instanceof IOException) { - throw (IOException) toThrow; - } else if (toThrow != null) { - throw (InstallerStopException) toThrow; - } - } - idsLoaded = true; - return ids; - } - - List getChannels() { - return channels; - } - - private int getChannelPriority(SoftwareChannel ch) { - SoftwareChannelSource src = this.channelInfos.get(ch); - if (src != null) { - return src.getPriority(); - } else { - int index = channels.indexOf(ch); - return index == -1 ? 0 : index; - } - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - Set cis = new HashSet<>(); - for (SoftwareChannel swch : channels) { - Set newInfos = swch.getStorage().loadComponentMetadata(id); - if (newInfos == null || newInfos.isEmpty()) { - continue; - } - if (!acceptAllSources) { - newInfos.removeAll(cis); - } - for (ComponentInfo ci : newInfos) { - ci.setPriority(getChannelPriority(swch)); - channelMap.putIfAbsent(ci, swch); - } - cis.addAll(newInfos); - if (!acceptAllSources) { - break; - } - } - return cis; - } - - public SoftwareChannel getOrigin(ComponentInfo ci) { - return channelMap.get(ci); - } - - @Override - public FileDownloader processDownloader(ComponentInfo info, FileDownloader dn) { - SoftwareChannel orig = getOrigin(info); - return orig != null ? orig.configureDownloader(info, dn) : dn; - } - - @Override - public MetadataLoader interceptMetadataLoader(ComponentInfo info, MetadataLoader delegate) { - SoftwareChannel orig = getOrigin(info); - if (orig instanceof ComponentCatalog.DownloadInterceptor) { - return ((ComponentCatalog.DownloadInterceptor) orig).interceptMetadataLoader(info, delegate); - } else { - return delegate; - } - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/ProxyConnectionFactory.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/ProxyConnectionFactory.java deleted file mode 100644 index 7607cdd0fcf0..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/ProxyConnectionFactory.java +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.net.ConnectException; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.URLConnectionFactory; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * Creates URLConnections to the given destination. Caches the decision about proxy. For the first - * {@link #openConnection(java.net.URI, org.graalvm.component.installer.URLConnectionFactory.Configure)}, - * the code wil open - *
    - *
  • a direct connection to the proxy - *
  • a connection through http proxy, if configured - *
  • a connection through https proxy, if configured - *
- * Users may forget to set both the http/https proxies, so the code will attempt to use whetaver is - * known. All those connections will attempt to connect to the destination. The first connection - * attempt that succeeds will be used. The mechanism (proxy setting, direct) that established the - * connection will be cached for subsequent requests to the same authority. Additional requests to - * the same location should not open additional probes then. - *

- * The factory is caching threads; initially at most 3 threads will be created for probes, then each - * request will reuse a thread from the thread pool (to watch time out the operation on the main - * thread). - * - * @author sdedic - */ -public class ProxyConnectionFactory implements URLConnectionFactory { - /** - * The max delay to connect to the final destination or open a proxy connection. In seconds. - */ - private static final int DEFAULT_CONNECT_DELAY = Integer.getInteger("org.graalvm.component.installer.connectDelaySec", 10); - - /** - * Delay in the case proxies are not used. Heuristics is not used at all, so the connection time - * may be longer. In seconds. - */ - private static final int DEFAULT_DIRECT_CONNECT_DELAY = Integer.getInteger("org.graalvm.component.installer.directConnectDelaySec", 20); - - private static final String PROXY_SCHEME_PREFIX = "http://"; // NOI18N - - private final Feedback feedback; - private final URL urlBase; - - // @GuardedBy(this) - private Connector winningConnector; - - /** - * Thread pool for connection attempts. Subsequent connections do not send unnecessary probes, - * but are done in a thread so the main thread may time out the operation. Most likely the - * threads will be allocated from this pool. - */ - private final ExecutorService connectors = Executors.newCachedThreadPool(); - - /** - * HTTP proxy settings. The default is taken from system environment variables and system - * property - */ - String envHttpProxy = System.getProperty("http_proxy", System.getenv("http_proxy")); // NOI18N - - /** - * HTTPS proxy settings. The default is taken from system environment variables and system - * property - */ - String envHttpsProxy = System.getProperty("https_proxy", System.getenv("https_proxy")); // NOI18N - - /** - * The configurable delay for this factory. Initialized to {@link #DEFAULT_CONNECT_DELAY}. - */ - private int connectDelay = DEFAULT_CONNECT_DELAY; - - private int directConnectDelay = DEFAULT_DIRECT_CONNECT_DELAY; - - public ProxyConnectionFactory(Feedback feedback, URL urlBase) { - this.feedback = feedback.withBundle(ProxyConnectionFactory.class); - this.urlBase = urlBase; - } - - /** - * Customizes connection timeouts. Base delay must be at least 0 (infinite wait). If the direct - * delay is negative, it is scaled from base delay using the same factor as the default timeouts - * - * @param delay base delay, 0 for infinite wait. Must not be negative - * @param directDelay single connection delay, negative to derive from the base delay - */ - public void setConnectDelay(int delay, int directDelay) { - if (delay < 0) { - throw new IllegalArgumentException(); - } - this.connectDelay = delay; - if (directDelay >= 0) { - this.directConnectDelay = directDelay; - } else { - // scale the base delay by the default connection factor - float factor = Math.min(1, ((float) DEFAULT_DIRECT_CONNECT_DELAY / DEFAULT_CONNECT_DELAY)); - this.directConnectDelay = Math.round(delay * factor); - } - } - - /** - * Scales the default timeouts by some factor. - * - * @param factor factor to scale the default timeouts. - */ - public void setConnectDelayFactor(float factor) { - this.connectDelay = Math.round(DEFAULT_CONNECT_DELAY * factor); - this.directConnectDelay = Math.round(DEFAULT_DIRECT_CONNECT_DELAY * factor); - } - - public ProxyConnectionFactory setProxy(boolean secure, String proxyURI) { - if (secure) { - envHttpsProxy = proxyURI; - } else { - envHttpProxy = proxyURI; - } - return this; - } - - public URLConnection openConnection(URI relative, Configure configCallback) throws IOException { - if (relative != null) { - try { - return openConnectionWithProxies(urlBase.toURI().resolve(relative).toURL(), configCallback); - } catch (URISyntaxException ex) { - throw new IOException(ex); - } - } else { - return openConnectionWithProxies(urlBase, configCallback); - } - } - - private class ConnectionContext { - private final Configure configCallback; - private final CountDownLatch countDown; - private final URL url; - private final List tryConnectors = new ArrayList<>(); - - // @GuardedBy(this) - private Connector winner; - // @GuardedBy(this) - private URLConnection openedConnection; - // @GuardedBy(this) - private IOException exProxy; - // @GuardedBy(this) - private IOException exDirect; - // @GuardedBy(this); - private int outcomes; - - ConnectionContext(URL url, Configure configCallback, CountDownLatch latch) { - this.configCallback = configCallback; - this.countDown = latch; - this.url = url; - } - - synchronized URLConnection getConnection() throws IOException { - if (openedConnection == null) { - if (exDirect != null) { - throw exDirect; - } else if (exProxy != null) { - throw exProxy; - } - throw new ConnectException(feedback.l10n("EXC_CannotConnectTo", url)); - } else { - return openedConnection; - } - } - - boolean setOutcome(Connector w, URLConnection opened) { - synchronized (this) { - if (winner != null) { - return false; - } - winner = w; - openedConnection = opened; - } - if (countDown != null) { - countDown.countDown(); - } - return true; - } - - void setOutcome(boolean direct, IOException e) { - synchronized (this) { - if (direct) { - exDirect = e; - } else { - exProxy = e; - } - if (++outcomes == tryConnectors.size()) { - countDown.countDown(); - } - } - } - - synchronized IOException getConnectException() { - if (exDirect != null) { - return exDirect; - } else if (exProxy != null) { - return exProxy; - } - return new ConnectException(feedback.l10n("EXC_TimeoutConnectTo", url)); - } - - synchronized void submit(Connector c) { - tryConnectors.add(c); - } - - void start() { - for (Connector c : tryConnectors) { - connectors.submit(c); - } - } - } - - /** - * Regexp to detect a scheme-like part. See https://tools.ietf.org/html/rfc3986#section-3.1. - */ - private static final Pattern SCHEME_REGEXP = Pattern.compile("^\\p{Alpha}[\\p{Alnum}+-.]*:", Pattern.CASE_INSENSITIVE); // NOI18N - - public static InetSocketAddress proxyAddress(String proxySpec) throws URISyntaxException { - if (proxySpec == null) { - return null; - } - String trimmed = proxySpec.trim(); - if ("".equals(trimmed)) { - return null; - } - // the URI is created just to parse the proxy specification. It won't be - // actually used as a whole to form URL or open connection - URI uri; - - try { - uri = new URI(trimmed); - } catch (URISyntaxException ex) { - // maybe the user did not include the http:// in the address spec. - if (SCHEME_REGEXP.matcher(trimmed).find()) { - // something that could be a scheme is already in, but still won't parse - throw ex; - } - try { - trimmed = PROXY_SCHEME_PREFIX + trimmed; - uri = new URI(trimmed); - } catch (URISyntaxException ex2) { - // no luck, throw the original exception: - throw ex; - } - if (uri.getHost() == null || uri.getPort() < 1) { - throw ex; - } - } - - // if the user forgets the scheme (http://) the string is misparsed and hostname - // becomes the scheme while the host part will be empty. Adding the "http://" in - // front - // fixes parsing at least for the host/port part. - if (uri.getScheme() == null || uri.getHost() == null) { - URI checkURI = null; - try { - checkURI = new URI(PROXY_SCHEME_PREFIX + trimmed); - if (!(checkURI.getHost() == null || checkURI.getPort() < 1)) { - uri = checkURI; - } - } catch (URISyntaxException ex) { - // better leave the specified value without the scheme. - } - } - InetSocketAddress address = InetSocketAddress.createUnresolved(uri.getHost(), uri.getPort()); - return address; - } - - final class Connector implements Runnable { - private final InetSocketAddress proxyAddress; - private URL url; - private ConnectionContext context; - - Connector(InetSocketAddress address) { - this.proxyAddress = address; - } - - InetSocketAddress getProxyAddress() { - return proxyAddress; - } - - boolean isDirect() { - return proxyAddress == null; - } - - boolean accepts(URL u) { - synchronized (this) { - return Objects.equals(u.getAuthority(), url.getAuthority()); - } - } - - Connector bind(ConnectionContext ctx) { - synchronized (this) { - context = ctx; - url = ctx.url; - } - return this; - } - - @Override - public void run() { - ConnectionContext ctx; - - synchronized (this) { - ctx = context; - context = null; - } - runWithContext(ctx); - } - - void runWithContext(ConnectionContext ctx) { - final Proxy proxy; - if (isDirect()) { - proxy = null; - } else { - proxy = new Proxy(Proxy.Type.HTTP, proxyAddress); - } - Configure configCallback = ctx.configCallback; - boolean won = false; - URLConnection test = null; - try { - test = proxy == null ? url.openConnection() : url.openConnection(proxy); - if (configCallback != null) { - configCallback.accept(test); - } - test.connect(); - if (test instanceof HttpURLConnection) { - HttpURLConnection htest = (HttpURLConnection) test; - int rcode = htest.getResponseCode(); - // using bad request 400 as a marker. All 4xx, 5xx codes should be handled this - // way to force - // the appropriate exception out. - if (rcode >= HttpURLConnection.HTTP_BAD_REQUEST) { - // force the exception, should fail with IOException - try { - htest.getInputStream().close(); - } catch (IOException ex) { - throw new HttpConnectionException(ex.getMessage(), ex, isDirect(), htest); - } - if (!isDirect()) { // this should not happen - throw new IOException(feedback.l10n("EXC_ProxyFailed", rcode)); - } - } - } - won = ctx.setOutcome(this, test); - } catch (IOException ex) { - ctx.setOutcome(isDirect(), ex); - } finally { - if (!won) { - if (test instanceof HttpURLConnection) { - ((HttpURLConnection) test).disconnect(); - } - } - } - } - } - - public static class HttpConnectionException extends IOException { - private static final long serialVersionUID = 1L; - private final boolean isDirect; - private final int retCode; - private final URL connectionUrl; - private final String response; - - public HttpConnectionException(String message, IOException cause, boolean isDirect, HttpURLConnection connection) throws IOException { - super(message, cause); - this.response = parseErrorResponse(connection); - this.retCode = connection.getResponseCode(); - this.connectionUrl = connection.getURL(); - this.isDirect = isDirect; - } - - private static String parseErrorResponse(HttpURLConnection connection) { - try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) { - return br.lines().reduce((s1, s2) -> s1 + "\n" + s2).orElse(""); - } catch (IOException t) { - return t.getLocalizedMessage(); - } - } - - public int getRetCode() { - return retCode; - } - - public String getResponse() { - return response; - } - - public URL getConnectionUrl() { - return connectionUrl; - } - - public boolean isProxy() { - return isDirect; - } - } - - List makeConnectors(String httpProxy, String httpsProxy) { - InetSocketAddress httpProxyAddress = null; - InetSocketAddress httpsProxyAddress = null; - - URISyntaxException httpError = null; - URISyntaxException httpsError = null; - - if (httpProxy != null) { - try { - httpProxyAddress = proxyAddress(httpProxy); - } catch (URISyntaxException ex) { - httpError = ex; - } - } - if (httpsProxy != null) { - if (!Objects.equals(httpProxy, httpsProxy)) { - try { - httpsProxyAddress = proxyAddress(httpsProxy); - } catch (URISyntaxException ex) { - httpsError = ex; - } - } - } - List tryConnectors = new ArrayList<>(); - - if (httpProxyAddress != null) { - tryConnectors.add(new Connector(httpProxyAddress)); - } - // do not attempt 2nd probe try if http+https are set to the same value. - if (httpsProxyAddress != null) { - tryConnectors.add(new Connector(httpsProxyAddress)); - } - - // something is there, but an error happened - if (httpError != null) { - feedback.error("WARN_HttpProxyGarbage", httpError, httpProxy); - } - if (httpsError != null) { - feedback.error("WARN_HttpsProxyGarbage", httpError, httpProxy); - } - if (tryConnectors.isEmpty()) { - // let the native support do its magic: - System.setProperty("java.net.useSystemProxies", "true"); - } - tryConnectors.add(new Connector(null)); - return tryConnectors; - } - - private URLConnection openConnectionWithProxies(URL url, Configure configCallback) throws IOException { - final CountDownLatch connected = new CountDownLatch(1); - String httpProxy; - String httpsProxy; - - Connector winner; - ConnectionContext ctx = new ConnectionContext(url, configCallback, connected); - - synchronized (this) { - httpProxy = envHttpProxy; - httpsProxy = envHttpsProxy; - winner = winningConnector; - } - - boolean haveProxy = false; - - // reuse the same detected direct / proxy for matching URLs. - if (winner != null && winner.accepts(url)) { - winner.bind(ctx); - // submit the winner so we can also recover from long connect delays - ctx.submit(winner); - // note: the winner will benefit from larger timeout as it is just one - // connection - } else { - List newConnectors = makeConnectors(httpProxy, httpsProxy); - haveProxy = newConnectors.size() > 1; - newConnectors.forEach(c -> ctx.submit(c.bind(ctx))); - } - - ctx.start(); - - int shouldDelay = haveProxy ? connectDelay : directConnectDelay; - - URLConnection res = null; - - try { - if (shouldDelay > 0) { - if (!connected.await(shouldDelay, TimeUnit.SECONDS)) { - throw ctx.getConnectException(); - } else { - // may also throw exception - res = ctx.getConnection(); - } - } else { - // wait indefinitely ... until network times out. - connected.await(); - res = ctx.getConnection(); - } - } catch (InterruptedException ex) { - throw new ConnectException(feedback.l10n("EXC_InterruptedConnectingTo", url)); - } - return res; - } - - @Override - public URLConnection createConnection(URL u, Configure configCallback) throws IOException { - try { - return openConnection(u.toURI(), configCallback); - } catch (URISyntaxException ex) { - throw new IOException(ex); - } - } - -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteCatalogDownloader.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteCatalogDownloader.java deleted file mode 100644 index ca7e95158b6f..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteCatalogDownloader.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.ServiceLoader; -import java.util.stream.Collectors; -import org.graalvm.component.installer.model.CatalogContents; -import org.graalvm.component.installer.CommandInput; -import org.graalvm.component.installer.Commands; -import org.graalvm.component.installer.CommonConstants; -import org.graalvm.component.installer.ComponentCollection; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SoftwareChannel; -import org.graalvm.component.installer.SoftwareChannelSource; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentStorage; - -public class RemoteCatalogDownloader implements SoftwareChannel { - private final CommandInput input; - private final Feedback feedback; - - private Iterable factories; - private List channelSources = new ArrayList<>(); - private CatalogContents union; - private String overrideCatalogSpec; - private String defaultCatalogSpec; - private boolean catalogURLParsed; - private boolean remoteSourcesAllowed = true; - - public RemoteCatalogDownloader(CommandInput in, Feedback out, String overrideCatalogSpec) { - this.input = in; - this.feedback = out.withBundle(RemoteCatalogDownloader.class); - this.overrideCatalogSpec = overrideCatalogSpec; - this.factories = ServiceLoader.load(SoftwareChannel.Factory.class); - } - - // tests only - public RemoteCatalogDownloader(CommandInput in, Feedback out, URL catalogURL) { - this(in, out, catalogURL == null ? null : catalogURL.toString()); - } - - public void addLocalChannelSource(SoftwareChannelSource src) { - src.setParameter("reportErrors", Boolean.FALSE.toString()); - channelSources.add(src); - } - - public void setRemoteSourcesAllowed(boolean remoteSourcesAllowed) { - this.remoteSourcesAllowed = remoteSourcesAllowed; - } - - public boolean isRemoteSourcesAllowed() { - return remoteSourcesAllowed; - } - - // for testing only - void setChannels(Iterable chan) { - this.factories = chan; - } - - public void setDefaultCatalog(String defaultCatalogSpec) { - this.defaultCatalogSpec = defaultCatalogSpec; - } - - public String getOverrideCatalogSpec() { - return overrideCatalogSpec; - } - - private MergeStorage mergedStorage; - - static final String CAP_CATALOG_URL_SUFFIX = "_" + CommonConstants.CAP_CATALOG_URL; // NOI18N - - @SuppressWarnings("ThrowableResultIgnored") - List parseChannelSources(String overrideSpec) { - List sources = new ArrayList<>(); - if (overrideSpec == null) { - return sources; - } - String[] parts = overrideSpec.split("\\|"); // NOI18N - for (String s : parts) { - sources.add(new SoftwareChannelSource(s)); // NOI18N - } - return sources; - } - - List getChannelSources() { - if (catalogURLParsed) { - return channelSources; - } - List sources = Collections.emptyList(); - if (remoteSourcesAllowed) { - if (overrideCatalogSpec != null) { - sources = parseChannelSources(overrideCatalogSpec); - } else { - sources = readChannelSources(); - if (sources.isEmpty()) { - sources = parseChannelSources(defaultCatalogSpec); - } - } - } - channelSources.addAll(0, sources); - catalogURLParsed = true; - return channelSources; - } - - private static final Comparator CHANNEL_KEY_COMPARATOR = new Comparator<>() { - @Override - public int compare(String o1, String o2) { - String k1 = o1.substring(CommonConstants.CAP_CATALOG_PREFIX.length()); - String k2 = o2.substring(CommonConstants.CAP_CATALOG_PREFIX.length()); - int i1 = Integer.MAX_VALUE; - int i2 = Integer.MAX_VALUE; - try { - i1 = Integer.parseInt(k1); - } catch (NumberFormatException ex) { - } - try { - i2 = Integer.parseInt(k2); - } catch (NumberFormatException ex) { - } - if (i1 != i2) { - return i1 - i2; - } - return k1.compareToIgnoreCase(k2); - } - }; - - private static Map lowercaseMap(Map map) { - Map res = new HashMap<>(); - for (String s : map.keySet()) { - res.put(s.toLowerCase(Locale.ENGLISH), map.get(s)); - } - return res; - } - - List readChannelSources(String pref, Map graalCaps) { - String prefix = pref + CommonConstants.CAP_CATALOG_PREFIX; - List orderedKeys = graalCaps.keySet().stream().filter((k) -> { - String lk = k.toLowerCase(Locale.ENGLISH); - return lk.startsWith(prefix) && lk.endsWith(CAP_CATALOG_URL_SUFFIX); - }).map((k) -> k.substring(0, k.length() - CAP_CATALOG_URL_SUFFIX.length())).collect(Collectors.toList()); - Collections.sort(orderedKeys, CHANNEL_KEY_COMPARATOR); - - List sources = new ArrayList<>(); - for (String key : orderedKeys) { - String url = graalCaps.get(key + CAP_CATALOG_URL_SUFFIX); - String lab = graalCaps.get(key + "_" + CommonConstants.CAP_CATALOG_LABEL); - if (url == null) { - continue; - } - SoftwareChannelSource s = new SoftwareChannelSource(url, lab); - for (String a : graalCaps.keySet()) { - if (!(a.startsWith(key) && a.length() > key.length() + 1)) { - continue; - } - String k = a.substring(key.length() + 1).toLowerCase(Locale.ENGLISH); - switch (k) { - case CommonConstants.CAP_CATALOG_LABEL: - case CommonConstants.CAP_CATALOG_URL: - continue; - } - s.setParameter(k, graalCaps.get(a)); - } - - sources.add(s); - } - return sources; - } - - List readChannelSources() { - List res; - Map lcEnv = lowercaseMap(input.parameters(false)); - res = readChannelSources(CommonConstants.ENV_VARIABLE_PREFIX.toLowerCase(Locale.ENGLISH), lcEnv); - if (res != null && !res.isEmpty()) { - return res; - } - if (remoteSourcesAllowed) { - return readChannelSources("", input.getLocalRegistry().getGraalCapabilities()); // NOI18N - } else { - return Collections.emptyList(); - } - } - - private MergeStorage mergeChannels() { - if (mergedStorage != null) { - return mergedStorage; - } - mergedStorage = new MergeStorage(input.getLocalRegistry(), feedback); - mergedStorage.setIgnoreCatalogErrors(input.hasOption(Commands.OPTION_IGNORE_CATALOG_ERRORS)); - for (SoftwareChannelSource spec : getChannelSources()) { - SoftwareChannel ch = null; - for (SoftwareChannel.Factory f : factories) { - ch = f.createChannel(spec, input, feedback); - if (ch != null) { - break; - } - } - if (ch != null) { - mergedStorage.addChannel(spec, ch); - } - } - return mergedStorage; - } - - SoftwareChannel delegate(ComponentInfo ci) { - return mergeChannels().getOrigin(ci); - } - - public ComponentCollection getRegistry() { - if (union == null) { - union = new CatalogContents(feedback, mergeChannels(), input.getLocalRegistry()); - // get errors early - union.getComponentIDs(); - } - return union; - } - - @Override - public FileDownloader configureDownloader(ComponentInfo cInfo, FileDownloader dn) { - return delegate(cInfo).configureDownloader(cInfo, dn); - } - - @Override - public ComponentStorage getStorage() { - return mergeChannels(); - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteComponentParam.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteComponentParam.java deleted file mode 100644 index 43e70c046c97..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemoteComponentParam.java +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.graalvm.component.installer.Archive; -import org.graalvm.component.installer.ComponentParam; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.InstallerStopException; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.persist.MetadataLoader; - -/** - * - * @author sdedic - */ -public abstract class RemoteComponentParam implements ComponentParam, MetadataLoader { - private final URL remoteURL; - private final String dispName; - private final String spec; - private final Feedback feedback; - private final ComponentInfo catalogInfo; - private ComponentInfo fileInfo; - private final boolean progress; - private boolean verifyJars; - private MetadataLoader fileLoader; - private boolean complete; - - protected RemoteComponentParam(ComponentInfo catalogInfo, String dispName, String spec, Feedback feedback, boolean progress) { - this.catalogInfo = catalogInfo; - this.dispName = dispName; - this.spec = spec; - this.feedback = feedback.withBundle(RemoteComponentParam.class); - this.progress = progress; - this.remoteURL = catalogInfo.getRemoteURL(); - } - - protected RemoteComponentParam(URL remoteURL, String dispName, String spec, Feedback feedback, boolean progress) { - this.catalogInfo = null; - this.dispName = dispName; - this.spec = spec; - this.feedback = feedback.withBundle(RemoteComponentParam.class); - this.remoteURL = remoteURL; - this.progress = progress; - } - - @Override - public String getSpecification() { - return spec; - } - - @Override - public String getDisplayName() { - return dispName; - } - - protected ComponentInfo getCatalogInfo() { - return catalogInfo; - } - - @Override - public MetadataLoader createMetaLoader() throws IOException { - if (catalogInfo != null) { - return this; - } else { - return createFileLoader(); - } - } - - public void setVerifyJars(boolean verifyJars) { - this.verifyJars = verifyJars; - } - - private Path localPath; - - @Override - public MetadataLoader createFileLoader() throws IOException { - if (fileLoader != null) { - return fileLoader; - } - return fileLoader = doCreateFileLoader(metadataFromLocal(downloadLocalFile())); - } - - protected MetadataLoader doCreateFileLoader(MetadataLoader delegate) { - return new DelegateMetaLoader(delegate); - } - - /** - * The delegate will ensure the ComponentParam will start to serve LOCAL ComponentInfo just - * after the delegate metaloader creates it. - */ - class DelegateMetaLoader implements MetadataLoader { - private final MetadataLoader delegate; - - DelegateMetaLoader(MetadataLoader delegate) { - this.delegate = delegate; - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - protected final ComponentInfo catalogInfo() { - return catalogInfo; - } - - @Override - public ComponentInfo getComponentInfo() { - fileInfo = configureComponentInfo(delegate.getComponentInfo()); - complete = true; - return fileInfo; - } - - protected ComponentInfo configureComponentInfo(ComponentInfo info) { - if (remoteURL != null) { - info.setRemoteURL(remoteURL); - } - return info; - } - - @Override - public List getErrors() { - return delegate.getErrors(); - } - - @Override - public Archive getArchive() throws IOException { - return delegate.getArchive(); - } - - @Override - public String getLicenseType() { - return delegate.getLicenseType(); - } - - @Override - public String getLicenseID() { - if (catalogInfo != null) { - String catalogLicense = catalogInfo.getLicensePath(); - if (catalogLicense != null && catalogLicense.contains("://")) { - return catalogLicense; - } - } - return delegate.getLicenseID(); - } - - @Override - public String getLicensePath() { - return delegate.getLicensePath(); - } - - @Override - public MetadataLoader infoOnly(boolean only) { - return delegate.infoOnly(only); - } - - @Override - public boolean isNoVerifySymlinks() { - return delegate.isNoVerifySymlinks(); - } - - @Override - public void loadPaths() throws IOException { - delegate.loadPaths(); - } - - @Override - public Map loadPermissions() throws IOException { - return delegate.loadPermissions(); - } - - @Override - public Map loadSymlinks() throws IOException { - return delegate.loadSymlinks(); - } - - @Override - public void setNoVerifySymlinks(boolean noVerifySymlinks) { - delegate.setNoVerifySymlinks(noVerifySymlinks); - } - - @Override - public ComponentInfo completeMetadata() throws IOException { - return delegate.completeMetadata(); - } - } - - /** - * Creates a metaloader for the local file. - * - * @param localFile the locally stored file - * @return loader reading the local file. - * @throws IOException error during construction of the loader. - */ - protected abstract MetadataLoader metadataFromLocal(Path localFile) throws IOException; - - private FileDownloader downloader; - - protected final FileDownloader getDownloader() { - return downloader; - } - - protected Path downloadLocalFile() throws IOException { - if (localPath != null && Files.isReadable(localPath)) { - return localPath; - } - try { - FileDownloader dn = createDownloader(); - if (catalogInfo != null) { - dn.setShaDigest(catalogInfo.getShaDigest()); - } - dn.setDisplayProgress(progress); - dn.download(); - localPath = dn.getLocalFile().toPath(); - downloader = dn; - } catch (FileNotFoundException ex) { - throw feedback.failure("REMOTE_ErrorDownloadingNotExist", ex, spec, remoteURL); - } - return localPath; - } - - protected FileDownloader createDownloader() { - FileDownloader dn = new FileDownloader(feedback.l10n("REMOTE_ComponentFileLabel", getDisplayName(), getSpecification()), remoteURL, feedback); - return dn; - } - - @Override - public boolean isComplete() { - return complete; - } - - @Override - public void close() throws IOException { - if (fileLoader != null) { - fileLoader.close(); - } - if (localPath != null) { - try { - Files.deleteIfExists(localPath); - } catch (IOException ex) { - feedback.error("REMOTE_CannotDeleteLocalFile", ex, localPath.toString(), ex.getLocalizedMessage()); - } - } - } - - @Override - public ComponentInfo getComponentInfo() { - return fileInfo != null ? fileInfo : catalogInfo; - } - - @Override - public List getErrors() { - return Collections.emptyList(); - } - - @Override - public Archive getArchive() { - try { - return createFileLoader().getArchive(); - } catch (IOException ex) { - throw feedback.failure("REMOTE_ErrorDownloadingComponent", ex, spec, remoteURL, ex.getLocalizedMessage()); - } - } - - @Override - public String getLicenseType() { - if (catalogInfo != null) { - return catalogInfo.getLicenseType(); - } else { - return null; - } - } - - protected FileDownloader createFileDownloader(URL remote, String desc, boolean mainFile) { - FileDownloader dn = new FileDownloader(desc, remote, feedback); - if (mainFile) { - configureRelatedDownloader(dn); - } - return dn; - } - - public String downloadAndHashLicense(String remote) { - String desc = getLicenseType(); - if (desc == null) { - desc = remote; - } - try { - URL u = SystemUtils.toURL(remote); - FileDownloader dn = createFileDownloader(u, feedback.l10n("LICENSE_RemoteLicenseDescription", desc), false); - dn.download(); - String s = String.join("\n", Files.readAllLines(dn.getLocalFile().toPath())); - return SystemUtils.digestString(s, false) /* + "_" + remote */; - } catch (IOException ex) { - throw feedback.failure("ERROR_DownloadLicense", ex, desc, ex.getLocalizedMessage()); - } - } - - /** - * License digest or URL. - */ - private String cachedLicenseID; - - @Override - public String getLicenseID() { - if (cachedLicenseID != null) { - return cachedLicenseID; - } - String s = getLicensePath(); - if (s != null && SystemUtils.isRemotePath(s)) { - // special case, so that the package will not be downloaded, if the - // catalog specifies HTTP remote path. - return cachedLicenseID = downloadAndHashLicense(s); - } - try { - return createFileLoader().getLicenseID(); - } catch (IOException ex) { - throw feedback.failure("REMOTE_ErrorDownloadingComponent", ex, spec, remoteURL, ex.getLocalizedMessage()); - } - } - - @Override - public String getLicensePath() { - if (catalogInfo != null) { - String lt = catalogInfo.getLicenseType(); - String path = catalogInfo.getLicensePath(); - if (lt == null || path != null) { - return path; - } - } - try { - return createFileLoader().getLicensePath(); - } catch (IOException ex) { - throw feedback.failure("REMOTE_ErrorDownloadingComponent", ex, spec, remoteURL, ex.getLocalizedMessage()); - } - } - - @Override - public MetadataLoader infoOnly(boolean only) { - return this; - } - - @Override - public boolean isNoVerifySymlinks() { - return true; - } - - @Override - public void loadPaths() { - } - - @Override - public Map loadPermissions() throws IOException { - return null; - } - - @Override - public Map loadSymlinks() throws IOException { - return null; - } - - @Override - public void setNoVerifySymlinks(boolean noVerifySymlinks) { - } - - @Override - public String getFullPath() { - return remoteURL.toString(); - } - - @Override - public String getShortName() { - return getComponentInfo().getId(); - } - - protected String getSpec() { - return spec; - } - - protected Feedback getFeedback() { - return feedback; - } - - protected boolean isProgress() { - return progress; - } - - protected boolean isVerifyJars() { - return verifyJars; - } - - protected Path getLocalPath() { - return localPath; - } -} diff --git a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemotePropertiesStorage.java b/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemotePropertiesStorage.java deleted file mode 100644 index 306e5e5e477c..000000000000 --- a/vm/src/org.graalvm.component.installer/src/org/graalvm/component/installer/remote/RemotePropertiesStorage.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.graalvm.component.installer.remote; - -import java.io.IOException; -import java.net.URL; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.graalvm.component.installer.Feedback; -import org.graalvm.component.installer.SystemUtils; -import org.graalvm.component.installer.Version; -import org.graalvm.component.installer.model.ComponentInfo; -import org.graalvm.component.installer.model.ComponentRegistry; -import org.graalvm.component.installer.model.RemoteInfoProcessor; -import org.graalvm.component.installer.persist.AbstractCatalogStorage; -import org.graalvm.component.installer.persist.ComponentPackageLoader; - -public class RemotePropertiesStorage extends AbstractCatalogStorage { - protected static final String PROPERTY_HASH = "hash"; // NOI18N - private static final String FORMAT_FLAVOUR = "Component\\.{0}"; // NOI18N - private static final String FORMAT_SINGLE_VERSION = "Component\\.{0}_{1}\\."; // NOI18N - - private final Properties catalogProperties; - private final String flavourRegex; - private final String singleRegex; - private final Version graalVersion; - - private RemoteInfoProcessor remoteProcessor = RemoteInfoProcessor.NONE; - - private Map filteredComponents; - - public RemotePropertiesStorage(Feedback fb, ComponentRegistry localReg, Properties catalogProperties, String graalSelector, Version gVersion, URL baseURL) { - super(localReg, fb, baseURL); - this.catalogProperties = catalogProperties; - flavourRegex = MessageFormat.format(FORMAT_FLAVOUR, graalSelector); - graalVersion = gVersion != null ? gVersion : localReg.getGraalVersion(); - singleRegex = MessageFormat.format(FORMAT_SINGLE_VERSION, - graalVersion.originalString(), graalSelector); - } - - public RemoteInfoProcessor getRemoteProcessor() { - return remoteProcessor; - } - - public void setRemoteProcessor(RemoteInfoProcessor remoteProcessor) { - this.remoteProcessor = remoteProcessor; - } - - /** - * Returns properties relevant for a specific component ID. May return properties for several - * versions of the component. Return {@code null} if the component does not exist at all. - * - * @param id component ID. - * @return Properties or {@code null} if component was not found. - */ - Properties filterPropertiesForVersions(String id) { - splitPropertiesToComponents(); - return filteredComponents.get(id); - } - - private void splitPropertiesToComponents() { - if (filteredComponents != null) { - return; - } - filteredComponents = new HashMap<>(); - - // known prefixes. Version will not be parsed again for therse. - Set knownPrefixes = new HashSet<>(); - - // already accepted prefixes - Set acceptedPrefixes = new HashSet<>(); - - Pattern flavourPattern = Pattern.compile("^" + flavourRegex, Pattern.CASE_INSENSITIVE); - Pattern singlePattern = Pattern.compile("^" + singleRegex, Pattern.CASE_INSENSITIVE); - - for (String s : catalogProperties.stringPropertyNames()) { - String cid; - String pn; - - int slashPos = s.indexOf('/'); - int secondSlashPos = s.indexOf('/', slashPos + 1); - int l; - - if (slashPos != -1 && secondSlashPos != -1) { - if (!flavourPattern.matcher(s).find()) { - continue; - } - pn = s.substring(slashPos + 1); - - String pref = s.substring(0, secondSlashPos); - - int lastSlashPos = s.indexOf('/', secondSlashPos + 1); - if (lastSlashPos == -1) { - lastSlashPos = secondSlashPos; - } - l = lastSlashPos + 1; - if (knownPrefixes.add(pref)) { - try { - Version vn = Version.fromString(s.substring(slashPos + 1, secondSlashPos)); - if (acceptsVersion(vn)) { - acceptedPrefixes.add(pref); - } - } catch (IllegalArgumentException ex) { - feedback.verboseOutput("REMOTE_BadComponentVersion", pn); - } - } - if (!acceptedPrefixes.contains(pref)) { - // ignore obsolete versions - continue; - } - - } else { - Matcher m = singlePattern.matcher(s); - if (!m.find()) { - continue; - } - // versionless component - l = m.end(); - // normalized version - pn = graalVersion.toString() + "/" + s.substring(l); - } - int dashPos = s.indexOf("-", l); - if (dashPos == -1) { - dashPos = s.length(); - } - cid = s.substring(l, dashPos); - String patchedCid = cid.replace("_", "-"); - String patchedPn = pn.replace(cid, patchedCid); - filteredComponents.computeIfAbsent(patchedCid, (unused) -> new Properties()).setProperty(patchedPn, catalogProperties.getProperty(s)); - } - } - - boolean acceptsVersion(Version vers) { - // also accept other minor patc - return graalVersion.installVersion().compareTo(vers.installVersion()) <= 0; - } - - @Override - public Set listComponentIDs() throws IOException { - Set ret = new HashSet<>(); - splitPropertiesToComponents(); - ret.addAll(filteredComponents.keySet()); - return ret; - } - - @Override - public Set loadComponentMetadata(String id) throws IOException { - Properties compProps = filterPropertiesForVersions(id); - if (compProps == null) { - return null; - } - Map infos = new HashMap<>(); - Set processedPrefixes = new HashSet<>(); - - for (String s : compProps.stringPropertyNames()) { - int slashPos = s.indexOf('/'); - int anotherSlashPos = s.indexOf('/', slashPos + 1); - - String vS = s.substring(0, slashPos); - String identity = anotherSlashPos == -1 ? vS : s.substring(0, anotherSlashPos); - if (!processedPrefixes.add(identity)) { - continue; - } - try { - Version.fromString(vS); - } catch (IllegalArgumentException ex) { - feedback.verboseOutput("REMOTE_BadComponentVersion", s); - continue; - } - ComponentInfo ci = createVersionedComponent(identity + "/", compProps, id, - anotherSlashPos == -1 ? "" : s.substring(slashPos + 1, anotherSlashPos)); - // just in case the catalog info is broken - if (ci != null) { - infos.put(identity, ci); - } - } - - return new HashSet<>(infos.values()); - } - - private ComponentInfo createVersionedComponent(String versoPrefix, Properties filtered, String id, String tag) throws IOException { - URL downloadURL; - String s = filtered.getProperty(versoPrefix + id.toLowerCase()); - if (s == null) { - return null; - } - // try { - downloadURL = SystemUtils.toURL(baseURL, s); - String prefix = versoPrefix + id.toLowerCase() + "-"; // NOI18N - String hashS = filtered.getProperty(prefix + PROPERTY_HASH); - byte[] hash = hashS == null ? null : toHashBytes(id, hashS); - - ComponentPackageLoader ldr = new ComponentPackageLoader(tag, - new PrefixedPropertyReader(prefix, filtered), - feedback); - ComponentInfo info = ldr.createComponentInfo(); - info.setRemoteURL(downloadURL); - info.setShaDigest(hash); - info.setOrigin(baseURL.toString()); - return configureComponentInfo(info); - } - - /** - * Allows to override, or supplement component information. - * - * @param info component info - * @return possibly modified or new instance. - */ - protected ComponentInfo configureComponentInfo(ComponentInfo info) { - return remoteProcessor.decorateComponent(info); - } - - static class PrefixedPropertyReader implements Function { - private final String compPrefix; - private final Properties props; - - PrefixedPropertyReader(String compPrefix, Properties props) { - this.compPrefix = compPrefix; - this.props = props; - } - - @Override - public String apply(String t) { - return props.getProperty(compPrefix + t); - } - } -} From 0ded87c5581cdc73f26b51ef1c428dd904f2932a Mon Sep 17 00:00:00 2001 From: Danilo Ansaloni Date: Tue, 20 Feb 2024 19:04:34 +0100 Subject: [PATCH 73/77] Remove references to the removed `gu` component. (cherry picked from commit a760dd290fc76677a2b00269887d436eec14e392) --- vm/mx.vm/ce-aarch64-complete | 2 +- vm/mx.vm/ce-complete | 2 +- vm/mx.vm/ce-darwin-aarch64-complete | 2 +- vm/mx.vm/ce-darwin-complete | 2 +- vm/mx.vm/ce-fastr | 2 +- vm/mx.vm/ce-js | 2 +- vm/mx.vm/ce-llvm | 2 +- vm/mx.vm/ce-no_native | 2 +- vm/mx.vm/ce-nodejs | 2 +- vm/mx.vm/ce-python | 2 +- vm/mx.vm/ce-test | 2 +- vm/mx.vm/ce-win-complete | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/vm/mx.vm/ce-aarch64-complete b/vm/mx.vm/ce-aarch64-complete index f6baf4ac45a5..2707eed95963 100644 --- a/vm/mx.vm/ce-aarch64-complete +++ b/vm/mx.vm/ce-aarch64-complete @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/espresso,/graal-js,/graal-nodejs,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,/wasm,graalpython,truffleruby -COMPONENTS=antlr4,cmp,cov,dap,gu,gvm,gwa,icu4j,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svml,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm +COMPONENTS=antlr4,cmp,cov,dap,gvm,gwa,icu4j,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svml,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm NATIVE_IMAGES=lib:pythonvm,graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jsvm,lib:javavm,lib:graal-nodejs,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,lib:llvmvm,native-image,lib:rubyvm,lib:wasmvm DISABLE_INSTALLABLES=False diff --git a/vm/mx.vm/ce-complete b/vm/mx.vm/ce-complete index e7d93e84b8f1..980ae334c3c9 100644 --- a/vm/mx.vm/ce-complete +++ b/vm/mx.vm/ce-complete @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/espresso,/graal-js,/graal-nodejs,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,/wasm,fastr,graalpython,truffleruby -COMPONENTS=antlr4,cmp,cov,dap,gu,gvm,gwa,icu4j,xz,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,R,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svml,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm +COMPONENTS=antlr4,cmp,cov,dap,gvm,gwa,icu4j,xz,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,R,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svml,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm NATIVE_IMAGES=lib:pythonvm,graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jsvm,lib:javavm,lib:graal-nodejs,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,lib:llvmvm,native-image,lib:rubyvm,lib:wasmvm DISABLE_INSTALLABLES=false diff --git a/vm/mx.vm/ce-darwin-aarch64-complete b/vm/mx.vm/ce-darwin-aarch64-complete index 617300d1dd2f..2dee06d7f1b2 100644 --- a/vm/mx.vm/ce-darwin-aarch64-complete +++ b/vm/mx.vm/ce-darwin-aarch64-complete @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/espresso,/graal-js,/graal-nodejs,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,/wasm,graalpython,truffleruby -COMPONENTS=antlr4,cmp,cov,dap,gu,gvm,gwa,icu4j,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm +COMPONENTS=antlr4,cmp,cov,dap,gvm,gwa,icu4j,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm NATIVE_IMAGES=lib:pythonvm,graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jsvm,lib:javavm,lib:graal-nodejs,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,lib:llvmvm,native-image,lib:rubyvm,lib:wasmvm DISABLE_INSTALLABLES=false diff --git a/vm/mx.vm/ce-darwin-complete b/vm/mx.vm/ce-darwin-complete index 43434dc25f37..37d668469214 100644 --- a/vm/mx.vm/ce-darwin-complete +++ b/vm/mx.vm/ce-darwin-complete @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/espresso,/graal-js,/graal-nodejs,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,/wasm,graalpython,truffleruby -COMPONENTS=antlr4,cmp,cov,dap,gu,gvm,gwa,icu4j,xz,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svml,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm +COMPONENTS=antlr4,cmp,cov,dap,gvm,gwa,icu4j,xz,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rby,rbyl,rgx,sdk,sdkl,svm,svmt,svml,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm NATIVE_IMAGES=lib:pythonvm,graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jsvm,lib:javavm,lib:graal-nodejs,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,lib:llvmvm,native-image,lib:rubyvm,lib:wasmvm DISABLE_INSTALLABLES=false diff --git a/vm/mx.vm/ce-fastr b/vm/mx.vm/ce-fastr index bef5f80c51e6..1fe02ea7729e 100644 --- a/vm/mx.vm/ce-fastr +++ b/vm/mx.vm/ce-fastr @@ -1,5 +1,5 @@ DYNAMIC_IMPORTS=/compiler,/graal-js,/sdk,/substratevm,/sulong,/tools,/truffle,fastr -COMPONENTS=antlr4,xz,R,cmp,cov,dap,gu,gvm,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,ni,nic,poly,polynative,pro,sdk,sdkl,svmt,svmnfi,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=antlr4,xz,R,cmp,cov,dap,gvm,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,ni,nic,poly,polynative,pro,sdk,sdkl,svmt,svmnfi,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=lib:jvmcicompiler NON_REBUILDABLE_IMAGES=lib:jvmcicompiler DISABLE_INSTALLABLES=False diff --git a/vm/mx.vm/ce-js b/vm/mx.vm/ce-js index b82d4baaa5a8..63da11084b9b 100644 --- a/vm/mx.vm/ce-js +++ b/vm/mx.vm/ce-js @@ -1,5 +1,5 @@ DYNAMIC_IMPORTS=/compiler,/graal-js,/regex,/sdk,/substratevm,/tools,/truffle -COMPONENTS=cmp,cov,dap,gu,gvm,icu4j,ins,insight,insightheap,js,jsl,jss,lg,lsp,nfi,nfi-libffi,ni,nic,nil,poly,polynative,pro,rgx,sdk,sdkl,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=cmp,cov,dap,gvm,icu4j,ins,insight,insightheap,js,jsl,jss,lg,lsp,nfi,nfi-libffi,ni,nic,nil,poly,polynative,pro,rgx,sdk,sdkl,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=lib:jsvm,lib:jvmcicompiler NON_REBUILDABLE_IMAGES=lib:jvmcicompiler DISABLE_INSTALLABLES=False diff --git a/vm/mx.vm/ce-llvm b/vm/mx.vm/ce-llvm index 097813dbef66..f9eb33e85ff4 100644 --- a/vm/mx.vm/ce-llvm +++ b/vm/mx.vm/ce-llvm @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/graal-js,/sdk,/substratevm,/sulong,/tools,/truffle -COMPONENTS=antlr4,cmp,cov,dap,gu,gvm,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi,nfi-libffi,poly,polynative,pro,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=antlr4,cmp,cov,dap,gvm,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi,nfi-libffi,poly,polynative,pro,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jvmcicompiler,lib:llvmvm DISABLE_INSTALLABLES=False diff --git a/vm/mx.vm/ce-no_native b/vm/mx.vm/ce-no_native index 3993761651eb..279961bcb44f 100644 --- a/vm/mx.vm/ce-no_native +++ b/vm/mx.vm/ce-no_native @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/graal-js,/sdk,/substratevm,/tools,/truffle -COMPONENTS=cmp,cov,dap,gu,gvm,ins,insight,insightheap,lsp,nfi-libffi,poly,polynative,pro,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=cmp,cov,dap,gvm,ins,insight,insightheap,lsp,nfi-libffi,poly,polynative,pro,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=false DISABLE_INSTALLABLES=ni,nil diff --git a/vm/mx.vm/ce-nodejs b/vm/mx.vm/ce-nodejs index 838b28d22581..b76ac335f897 100644 --- a/vm/mx.vm/ce-nodejs +++ b/vm/mx.vm/ce-nodejs @@ -1,5 +1,5 @@ DYNAMIC_IMPORTS=/compiler,/graal-js,/graal-nodejs,/sdk,/substratevm,/tools,/truffle -COMPONENTS=cmp,cov,dap,gu,gvm,ins,insight,insightheap,js,jsl,jss,lg,lsp,nfi-libffi,njs,njsl,ni,nic,nil,poly,polynative,pro,sdk,sdkl,sjvm,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=cmp,cov,dap,gvm,ins,insight,insightheap,js,jsl,jss,lg,lsp,nfi-libffi,njs,njsl,ni,nic,nil,poly,polynative,pro,sdk,sdkl,sjvm,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:graal-nodejs,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,native-image NON_REBUILDABLE_IMAGES=lib:jvmcicompiler DISABLE_INSTALLABLES=False diff --git a/vm/mx.vm/ce-python b/vm/mx.vm/ce-python index 6a412a9fa3e7..5d681e66345e 100644 --- a/vm/mx.vm/ce-python +++ b/vm/mx.vm/ce-python @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,graalpython -COMPONENTS=antlr4,cmp,cov,dap,dis,gu,gvm,icu4j,xz,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,pbm,pmh,poly,polynative,pro,pyn,pynl,rgx,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=antlr4,cmp,cov,dap,dis,gvm,icu4j,xz,ins,insight,insightheap,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,pbm,pmh,poly,polynative,pro,pyn,pynl,rgx,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=lib:pythonvm,lib:jvmcicompiler,graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld DISABLE_INSTALLABLES=False diff --git a/vm/mx.vm/ce-test b/vm/mx.vm/ce-test index 6ea756afc9fb..bdca53e08b6a 100644 --- a/vm/mx.vm/ce-test +++ b/vm/mx.vm/ce-test @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/graal-js,/regex,/sdk,/substratevm,/tools,/truffle -COMPONENTS=cmp,cov,dap,dis,gu,gvm,icu4j,ins,insight,insightheap,lg,llp,lsp,nfi-libffi,ni,nic,nil,nju,njucp,poly,polynative,pro,rgx,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json +COMPONENTS=cmp,cov,dap,dis,gvm,icu4j,ins,insight,insightheap,lg,llp,lsp,nfi-libffi,ni,nic,nil,nju,njucp,poly,polynative,pro,rgx,sdk,sdkl,tfl,tfla,tflc,tflm,truffle-json NATIVE_IMAGES=graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,native-image DISABLE_INSTALLABLES=llp diff --git a/vm/mx.vm/ce-win-complete b/vm/mx.vm/ce-win-complete index b23d8849c23d..6c3f3e2e1d99 100644 --- a/vm/mx.vm/ce-win-complete +++ b/vm/mx.vm/ce-win-complete @@ -1,4 +1,4 @@ DYNAMIC_IMPORTS=/compiler,/espresso,/graal-js,/graal-nodejs,/regex,/sdk,/substratevm,/sulong,/tools,/truffle,/wasm,graalpython -COMPONENTS=antlr4,cmp,cov,dap,gu,gvm,gwa,icu4j,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rgx,sdk,sdkl,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm +COMPONENTS=antlr4,cmp,cov,dap,gvm,gwa,icu4j,ins,insight,insightheap,js,jsl,jss,lg,llp,llrc,llrl,llrn,lsp,nfi-libffi,nfi,ni,nic,nil,njs,njsl,poly,polynative,pro,pyn,pynl,rgx,sdk,sdkl,svm,svmt,svmnfi,svmsl,tfl,tfla,tflc,tflm,truffle-json,vvm NATIVE_IMAGES=lib:pythonvm,graalvm-native-binutil,graalvm-native-clang,graalvm-native-clang-cl,graalvm-native-clang++,graalvm-native-flang,graalvm-native-ld,lib:jsvm,lib:javavm,lib:graal-nodejs,lib:jvmcicompiler,lib:native-image-agent,lib:native-image-diagnostics-agent,lib:llvmvm,native-image,lib:wasmvm DISABLE_INSTALLABLES=False From 738a5e0b5fb9b3709828f4ff09695c71a802f96e Mon Sep 17 00:00:00 2001 From: Andrii Konchyn Date: Wed, 27 Mar 2024 10:31:41 +0000 Subject: [PATCH 74/77] [GR-52910] Backport to 24.0: Fix caching of Regexps. PullRequest: truffleruby/4219 --- vm/mx.vm/suite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index bb13696e107a..564f5e81ed13 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -49,7 +49,7 @@ }, { "name": "truffleruby", - "version": "264c7e0aa54d165c2d143054248098e6db0204e5", + "version": "703c2de84470cc6b8c05971b954582b6214577b3", "dynamic": True, "urls": [ {"url": "https://github.com/oracle/truffleruby.git", "kind": "git"}, From e9edc2018e50a476012279c51708141c178b3d89 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Wed, 27 Mar 2024 16:03:25 +0100 Subject: [PATCH 75/77] basic array copy: less virtualization for illegal values (cherry picked from commit e708b7b03be9854be47c8c8425384c933cb7a91a) --- .../nodes/BasicArrayCopyNode.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/BasicArrayCopyNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/BasicArrayCopyNode.java index 83c90a192163..217c061346fb 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/BasicArrayCopyNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/BasicArrayCopyNode.java @@ -255,6 +255,39 @@ public boolean isExact() { return false; } + /** + * When dealing with arrays of primitives it's possible to store a larger value into a smaller + * component type array. For example a long value can be written into a byte array by storing + * the larger value in the first entry and storing {@code Illegal} in the slots whose value + * comes from the long value. So a long in a byte array would be a long value followed by 7 + * {@code Illegal} values. That also means such a write much be treated as a group by arraycopy + * so reads and writes can't be performed in the middle of the illegal values. + *

+ * So to ensure that an arraycopy properly treats these kinds of writes as group, it's + * sufficient to check that the first value is not {@code Illegal} and that the next value after + * the end is not {@code Illegal} since {@code Illegal} values only appear in the tail of these + * groups. + */ + private static boolean ensureIllegalValuesCanBeRepresented(int length, int srcPos, int srcLength, int dstPos, int dstLength, VirtualObjectNode src, VirtualObjectNode dst, VirtualizerTool tool) { + if (length <= 0) { + return true; + } + // check source + ValueNode firstSrcEntry = tool.getEntry(src, srcPos); + ValueNode followingSrcEntry = srcPos + length < srcLength ? tool.getEntry(src, srcPos + length) : null; + if (firstSrcEntry.isIllegalConstant() || followingSrcEntry != null && followingSrcEntry.isIllegalConstant()) { + return false; + } + + // check dst + ValueNode firstDstEntry = tool.getEntry(dst, dstPos); + ValueNode followingDstEntry = dstPos + length < dstLength ? tool.getEntry(dst, dstPos + length) : null; + if (firstDstEntry.isIllegalConstant() || followingDstEntry != null && followingDstEntry.isIllegalConstant()) { + return false; + } + return true; + } + @Override public void virtualize(VirtualizerTool tool) { ValueNode sourcePosition = tool.getAlias(getSourcePosition()); @@ -288,6 +321,9 @@ public void virtualize(VirtualizerTool tool) { if (!checkEntryTypes(srcPosInt, len, srcVirtual, destVirtual.type().getComponentType(), tool)) { return; } + if (!ensureIllegalValuesCanBeRepresented(len, srcPosInt, srcVirtual.entryCount(), destPosInt, destVirtual.entryCount(), srcVirtual, destVirtual, tool)) { + return; + } if (srcVirtual == destVirtual && srcPosInt < destPosInt) { // must copy backwards to avoid losing elements for (int i = len - 1; i >= 0; i--) { From 3a9a3fe5d3f45d1c2f8c8328b2d260946aeb252f Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Fri, 5 Apr 2024 14:59:01 +0000 Subject: [PATCH 76/77] GR-53257 : release GraalVM 24.0.1 --- compiler/mx.compiler/suite.py | 2 +- espresso/mx.espresso/suite.py | 2 +- regex/mx.regex/suite.py | 2 +- sdk/mx.sdk/suite.py | 2 +- substratevm/mx.substratevm/suite.py | 2 +- tools/mx.tools/suite.py | 2 +- truffle/mx.truffle/suite.py | 2 +- vm/mx.vm/suite.py | 8 ++++---- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/mx.compiler/suite.py b/compiler/mx.compiler/suite.py index 37da791f9c40..0731335748f9 100644 --- a/compiler/mx.compiler/suite.py +++ b/compiler/mx.compiler/suite.py @@ -5,7 +5,7 @@ "groupId" : "org.graalvm.compiler", "version" : "24.0.1", - "release" : False, + "release" : True, "url" : "http://www.graalvm.org/", "developer" : { "name" : "GraalVM Development", diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index 9cc5e3dff92d..a0f1531885f7 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -25,7 +25,7 @@ "mxversion": "6.44.0", "name": "espresso", "version" : "24.0.1", - "release" : False, + "release" : True, "groupId" : "org.graalvm.espresso", "url" : "https://www.graalvm.org/reference-manual/java-on-truffle/", "developer" : { diff --git a/regex/mx.regex/suite.py b/regex/mx.regex/suite.py index bf90debb6b3a..dc87f492ad90 100644 --- a/regex/mx.regex/suite.py +++ b/regex/mx.regex/suite.py @@ -44,7 +44,7 @@ "name" : "regex", "version" : "24.0.1", - "release" : False, + "release" : True, "groupId" : "org.graalvm.regex", "url" : "http://www.graalvm.org/", "developer" : { diff --git a/sdk/mx.sdk/suite.py b/sdk/mx.sdk/suite.py index 889d26fa0979..10b54766c296 100644 --- a/sdk/mx.sdk/suite.py +++ b/sdk/mx.sdk/suite.py @@ -42,7 +42,7 @@ "mxversion": "6.53.2", "name" : "sdk", "version" : "24.0.1", - "release" : False, + "release" : True, "sourceinprojectwhitelist" : [], "url" : "https://github.com/oracle/graal", "groupId" : "org.graalvm.sdk", diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py index 04ba4e31500e..4101b50a7e52 100644 --- a/substratevm/mx.substratevm/suite.py +++ b/substratevm/mx.substratevm/suite.py @@ -3,7 +3,7 @@ "mxversion": "6.27.1", "name": "substratevm", "version" : "24.0.1", - "release" : False, + "release" : True, "url" : "https://github.com/oracle/graal/tree/master/substratevm", "groupId" : "org.graalvm.nativeimage", diff --git a/tools/mx.tools/suite.py b/tools/mx.tools/suite.py index 4e0eb547d9ce..a2b1749e94aa 100644 --- a/tools/mx.tools/suite.py +++ b/tools/mx.tools/suite.py @@ -27,7 +27,7 @@ "groupId" : "org.graalvm.tools", "version" : "24.0.1", - "release" : False, + "release" : True, "url" : "http://openjdk.java.net/projects/graal", "developer" : { "name" : "GraalVM Development", diff --git a/truffle/mx.truffle/suite.py b/truffle/mx.truffle/suite.py index a0d0b277da91..ce1c9b8f3fe6 100644 --- a/truffle/mx.truffle/suite.py +++ b/truffle/mx.truffle/suite.py @@ -42,7 +42,7 @@ "mxversion": "7.0.3", "name" : "truffle", "version" : "24.0.1", - "release" : False, + "release" : True, "groupId" : "org.graalvm.truffle", "sourceinprojectwhitelist" : [], "url" : "http://openjdk.java.net/projects/graal", diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 1331ed7a1a72..7dda17f6df7e 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -2,7 +2,7 @@ "name": "vm", "version" : "24.0.1", "mxversion": "6.41.0", - "release" : False, + "release" : True, "groupId" : "org.graalvm", "url" : "http://www.graalvm.org/", @@ -33,7 +33,7 @@ "name": "graal-nodejs", "subdir": True, "dynamic": True, - "version": "7db28239f0da1087baf9c409fdb206b423c991b6", + "version": "d1a4fb72a45e37bdfd4b018ee4d59a88c4b23dc7", "urls" : [ {"url" : "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] @@ -42,7 +42,7 @@ "name": "graal-js", "subdir": True, "dynamic": True, - "version": "7db28239f0da1087baf9c409fdb206b423c991b6", + "version": "d1a4fb72a45e37bdfd4b018ee4d59a88c4b23dc7", "urls": [ {"url": "https://github.com/graalvm/graaljs.git", "kind" : "git"}, ] @@ -65,7 +65,7 @@ }, { "name": "graalpython", - "version": "2ff2ae7428da4a209340248cc672deea5f173ef4", + "version": "b2a38ff709eb9e40ca7e18ba259ff925aae1cd2", "dynamic": True, "urls": [ {"url": "https://github.com/graalvm/graalpython.git", "kind": "git"}, From d3ba9c443181b92cce2e02080ecb2331abd90d33 Mon Sep 17 00:00:00 2001 From: Marouane El Hallaoui Date: Fri, 5 Apr 2024 15:08:42 +0000 Subject: [PATCH 77/77] follow up fix: graalpython import --- vm/mx.vm/suite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/mx.vm/suite.py b/vm/mx.vm/suite.py index 7dda17f6df7e..71e0317c3ccc 100644 --- a/vm/mx.vm/suite.py +++ b/vm/mx.vm/suite.py @@ -65,7 +65,7 @@ }, { "name": "graalpython", - "version": "b2a38ff709eb9e40ca7e18ba259ff925aae1cd2", + "version": "0b2a38ff709eb9e40ca7e18ba259ff925aae1cd2", "dynamic": True, "urls": [ {"url": "https://github.com/graalvm/graalpython.git", "kind": "git"},