From 4853830658a67ec6b1d68c4dc8ee4662a3956f39 Mon Sep 17 00:00:00 2001 From: DeepSource Bot Date: Mon, 1 Nov 2021 05:28:56 +0000 Subject: [PATCH 1/7] Add .deepsource.toml --- .deepsource.toml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000000..dac4e4f3e1 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,26 @@ +version = 1 + +[[analyzers]] +name = "python" +enabled = true + + [analyzers.meta] + runtime_version = "3.x.x" + +[[analyzers]] +name = "javascript" +enabled = true + + [analyzers.meta] + plugins = ["react"] + +[[analyzers]] +name = "shell" +enabled = true + +[[analyzers]] +name = "java" +enabled = true + + [analyzers.meta] + runtime_version = "15" From dd1a294c00d3e4b085f6ffdae639f0d1bf01b791 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Fri, 12 Nov 2021 23:08:12 +1030 Subject: [PATCH 2/7] added creatToken, createTokens functions --- .../functions/TokenCopyDeleteFunctions.java | 64 ++++++++++++++++++- .../java/net/rptools/maptool/model/Asset.java | 2 +- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java b/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java index 8d2c645153..31554fe217 100644 --- a/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/TokenCopyDeleteFunctions.java @@ -46,8 +46,12 @@ public class TokenCopyDeleteFunctions extends AbstractFunction { private static final String COPY_FUNC = "copyToken"; private static final String REMOVE_FUNC = "removeToken"; + private static final String CREATE_TOKEN_FUNC = "createToken"; + + private static final String CREATE_TOKENS_FUNC = "createTokens"; + private TokenCopyDeleteFunctions() { - super(1, 4, COPY_FUNC, REMOVE_FUNC); + super(1, 4, COPY_FUNC, REMOVE_FUNC, CREATE_TOKEN_FUNC, CREATE_TOKENS_FUNC); } public static TokenCopyDeleteFunctions getInstance() { @@ -67,8 +71,11 @@ public Object childEvaluate( Token token = FunctionUtil.getTokenFromParam(resolver, functionName, parameters, 0, 2); int nCopies = psize > 1 ? FunctionUtil.paramAsInteger(functionName, parameters, 1, false) : 1; JsonObject newVals; - if (psize > 3) newVals = FunctionUtil.paramAsJsonObject(functionName, parameters, 3); - else newVals = new JsonObject(); + if (psize > 3) { + newVals = FunctionUtil.paramAsJsonObject(functionName, parameters, 3); + } else { + newVals = new JsonObject(); + } return copyTokens((MapToolVariableResolver) resolver, token, nCopies, newVals); } @@ -80,9 +87,60 @@ public Object childEvaluate( return deleteToken(token); } + if (functionName.equalsIgnoreCase(CREATE_TOKEN_FUNC)) { + FunctionUtil.checkNumberParam(functionName, parameters, 1, 1); + JsonObject vals = FunctionUtil.paramAsJsonObject(functionName, parameters, 0); + return createToken((MapToolVariableResolver) resolver, vals); + } + + if (functionName.equalsIgnoreCase(CREATE_TOKENS_FUNC)) { + FunctionUtil.checkNumberParam(functionName, parameters, 1, 1); + JsonArray vals = FunctionUtil.paramAsJsonArray(functionName, parameters, 0); + var tokenIds = new JsonArray(); + for (int i = 0; i < vals.size(); i++) { + tokenIds.add( + createToken((MapToolVariableResolver) resolver, vals.get(i).getAsJsonObject())); + } + return tokenIds; + } + throw new ParserException(I18N.getText("macro.function.general.unknownFunction", functionName)); } + private String createToken(MapToolVariableResolver resolver, JsonObject vals) + throws ParserException { + + if (!vals.has("name")) { + throw new ParserException(I18N.getText("macro.function.tokenCopyDelete.noName")); + } + String name = vals.get("name").getAsString(); + + if (!vals.has("tokenImage")) { + throw new ParserException(I18N.getText("macro.function.tokenCopyDelete.noImage")); + } + String tokenImage = vals.get("tokenImage").getAsString(); + + Zone zone = MapTool.getFrame().getCurrentZoneRenderer().getZone(); + List allTokens = zone.getTokens(); + Token t = new Token(name, new MD5Key(tokenImage)); + + // Make sure the exposedAreaGUID stays unique + if (allTokens != null) { + for (Token tok : allTokens) { + GUID tea = tok.getExposedAreaGUID(); + if (tea != null && tea.equals(t.getExposedAreaGUID())) { + t.setExposedAreaGUID(new GUID()); + } + } + } + // setTokenValues() handles the naming of the new token and must be called even if + // nothing was passed for the updates parameter (newVals). + setTokenValues(t, vals, zone, resolver); + + MapTool.serverCommand().putToken(zone.getId(), t); + return t.getId().toString(); + } + /** * Deletes the token. * diff --git a/src/main/java/net/rptools/maptool/model/Asset.java b/src/main/java/net/rptools/maptool/model/Asset.java index c0d981470e..2fa9868643 100644 --- a/src/main/java/net/rptools/maptool/model/Asset.java +++ b/src/main/java/net/rptools/maptool/model/Asset.java @@ -77,7 +77,7 @@ public enum Type { private final boolean stringType; /** Method uses to create an {@code Asset} of this type. */ - private final BiFunction factory; + private final transient BiFunction factory; /** The default extension for this type. */ private final String defaultExtension; From 5b70d3b88035f12f1f789da1e8cdb2bc446be229 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Fri, 12 Nov 2021 23:21:09 +1030 Subject: [PATCH 3/7] remove unwanted file --- .deepsource.toml | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index dac4e4f3e1..0000000000 --- a/.deepsource.toml +++ /dev/null @@ -1,26 +0,0 @@ -version = 1 - -[[analyzers]] -name = "python" -enabled = true - - [analyzers.meta] - runtime_version = "3.x.x" - -[[analyzers]] -name = "javascript" -enabled = true - - [analyzers.meta] - plugins = ["react"] - -[[analyzers]] -name = "shell" -enabled = true - -[[analyzers]] -name = "java" -enabled = true - - [analyzers.meta] - runtime_version = "15" From 599fcf21a8416f72ed13630adf8ba9615f402a8c Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Fri, 12 Nov 2021 23:29:21 +1030 Subject: [PATCH 4/7] fix error messages --- .../resources/net/rptools/maptool/language/i18n.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/net/rptools/maptool/language/i18n.properties b/src/main/resources/net/rptools/maptool/language/i18n.properties index f1c023ebe3..87985662ec 100644 --- a/src/main/resources/net/rptools/maptool/language/i18n.properties +++ b/src/main/resources/net/rptools/maptool/language/i18n.properties @@ -1817,7 +1817,8 @@ macro.function.tokenBarFunction.unknownBar = Error with function "{0}": # String Property # {0} = value the user passed. macro.function.varsFromstrProp.wrongArgs = varsFromStrProp called with 3 arguments, but second argument "{0}" was not one of NONE, SUFFIXED, or UNSUFFIXED. - +macro.function.tokenCopyDelete.noName = No name specified for token. +macro.function.tokenCopyDelete.noImage = No image specified for token. macro.function.markdown.unknownType = Unknown Markdown type {0}. From 987bd4b233ae472640d34a40d55c36599ad25da3 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sat, 13 Nov 2021 16:54:11 +1030 Subject: [PATCH 5/7] add @this fors static data --- .deepsource.toml | 26 ------------------- .../client/functions/DataFunctions.java | 4 +-- .../maptool/model/library/Library.java | 3 +-- .../maptool/model/library/LibraryManager.java | 21 +++++++++++++++ .../model/library/addon/AddOnLibrary.java | 2 +- .../model/library/token/LibraryToken.java | 2 +- 6 files changed, 26 insertions(+), 32 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index dac4e4f3e1..0000000000 --- a/.deepsource.toml +++ /dev/null @@ -1,26 +0,0 @@ -version = 1 - -[[analyzers]] -name = "python" -enabled = true - - [analyzers.meta] - runtime_version = "3.x.x" - -[[analyzers]] -name = "javascript" -enabled = true - - [analyzers.meta] - plugins = ["react"] - -[[analyzers]] -name = "shell" -enabled = true - -[[analyzers]] -name = "java" -enabled = true - - [analyzers.meta] - runtime_version = "15" diff --git a/src/main/java/net/rptools/maptool/client/functions/DataFunctions.java b/src/main/java/net/rptools/maptool/client/functions/DataFunctions.java index 268972d0f3..cc52565b08 100644 --- a/src/main/java/net/rptools/maptool/client/functions/DataFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/DataFunctions.java @@ -190,12 +190,12 @@ public Object childEvaluate( String namespace = parameters.get(0).toString(); String path = parameters.get(1).toString(); var context = MapTool.getParser().getContext(); - var libOpt = new LibraryManager().getLibrary(namespace); + var libOpt = new LibraryManager().getLibraryForMTScriptCall(namespace, context); var lib = libOpt.orElseThrow( () -> new ParserException(I18N.getText("library.error.notFound", namespace))); DataValue dataValue; - if (lib.canMTScriptAccessPrivate(context, namespace)) { + if (lib.canMTScriptAccessPrivate(context)) { dataValue = lib.getLibraryData().thenCompose(data -> data.getStaticData(path)).join(); } else { dataValue = diff --git a/src/main/java/net/rptools/maptool/model/library/Library.java b/src/main/java/net/rptools/maptool/model/library/Library.java index 02f8d3d7df..a276097425 100644 --- a/src/main/java/net/rptools/maptool/model/library/Library.java +++ b/src/main/java/net/rptools/maptool/model/library/Library.java @@ -185,8 +185,7 @@ public interface Library { * Returns if the context is able to access the private values in the library. * * @param context the current MTScript context to check. - * @param namespace the namespace of the library. * @return if the context is able to access the private values in the library. */ - boolean canMTScriptAccessPrivate(MapToolMacroContext context, String namespace); + boolean canMTScriptAccessPrivate(MapToolMacroContext context); } diff --git a/src/main/java/net/rptools/maptool/model/library/LibraryManager.java b/src/main/java/net/rptools/maptool/model/library/LibraryManager.java index 65dec74430..c9f3f35c3c 100644 --- a/src/main/java/net/rptools/maptool/model/library/LibraryManager.java +++ b/src/main/java/net/rptools/maptool/model/library/LibraryManager.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import net.rptools.maptool.client.AppActions; import net.rptools.maptool.client.MapTool; +import net.rptools.maptool.client.MapToolMacroContext; import net.rptools.maptool.model.library.addon.AddOnLibrary; import net.rptools.maptool.model.library.addon.AddOnLibraryManager; import net.rptools.maptool.model.library.addon.TransferableAddOnLibrary; @@ -231,6 +232,26 @@ public Optional getLibraryInfo(String namespace) } } + /** + * Returns the library with the specified namespace. This version of the method can be used to map + * "@this" to the current library a MTScript macro is running from. + * + * @param namespace the namespace of the library to get. + * @param context the context to use when mapping "@this" to the current library. + * @return the library with the specified namespace. + */ + public Optional getLibraryForMTScriptCall( + String namespace, MapToolMacroContext context) { + String ns = namespace; + if ("@this".equalsIgnoreCase(namespace)) { + if (context == null || context.getSource() == null || context.getSource().isEmpty()) { + return Optional.empty(); + } + ns = context.getSource().replaceFirst("(?i)^lib:", ""); + } + return getLibrary(ns); + } + /** * Returns the library for a given namespace. * diff --git a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java index 74855284ba..aec75231ac 100644 --- a/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java +++ b/src/main/java/net/rptools/maptool/model/library/addon/AddOnLibrary.java @@ -315,7 +315,7 @@ public CompletableFuture> getAssociatedToken() { } @Override - public boolean canMTScriptAccessPrivate(MapToolMacroContext context, String namespace) { + public boolean canMTScriptAccessPrivate(MapToolMacroContext context) { String source = context.getSource().replaceFirst("(?i)^lib:", ""); return context == null || source.equalsIgnoreCase(namespace); } diff --git a/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java b/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java index 8b10a7b0c7..60fdfe1e43 100644 --- a/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java +++ b/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java @@ -334,7 +334,7 @@ public CompletableFuture> getAssociatedToken() { } @Override - public boolean canMTScriptAccessPrivate(MapToolMacroContext context, String namespace) { + public boolean canMTScriptAccessPrivate(MapToolMacroContext context) { return false; // Library Tokens don't have private data } From 83c03d67343103780cb5b43317a5e7b1318cb483 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Mon, 15 Nov 2021 01:42:44 +1030 Subject: [PATCH 6/7] fixes for several issues... campaign load, numeric lib properties, and deleting tokens --- .../functions/UserDefinedMacroFunctions.java | 32 +++------- .../model/library/token/LibraryToken.java | 12 +++- .../library/token/LibraryTokenManager.java | 12 ++-- .../model/library/token/TokenLibraryData.java | 22 +++++-- .../rptools/maptool/util/EventMacroUtil.java | 63 +++++++++++++++++++ 5 files changed, 103 insertions(+), 38 deletions(-) diff --git a/src/main/java/net/rptools/maptool/client/functions/UserDefinedMacroFunctions.java b/src/main/java/net/rptools/maptool/client/functions/UserDefinedMacroFunctions.java index c24ed66087..7c02e4532f 100644 --- a/src/main/java/net/rptools/maptool/client/functions/UserDefinedMacroFunctions.java +++ b/src/main/java/net/rptools/maptool/client/functions/UserDefinedMacroFunctions.java @@ -34,10 +34,9 @@ import net.rptools.maptool.client.ui.syntax.MapToolScriptSyntax; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.MacroButtonProperties; -import net.rptools.maptool.model.library.Library; +import net.rptools.maptool.model.Token; import net.rptools.maptool.model.library.LibraryManager; import net.rptools.maptool.util.EventMacroUtil; -import net.rptools.maptool.util.threads.ThreadExecutionHelper; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; import net.rptools.parser.VariableResolver; @@ -244,29 +243,12 @@ public boolean isFunctionDefined(String name) { */ public void handleCampaignLoadMacroEvent() { userDefinedFunctions.clear(); - new LibraryManager() - .getLegacyEventTargets(ON_LOAD_CAMPAIGN_CALLBACK) - .thenApply( - libs -> { - new ThreadExecutionHelper() - .runOnSwingThread( - () -> { - for (Library lib : libs) { - var token = lib.getAssociatedToken().get(); - if (token.isPresent()) { // only supported for lib tokens - EventMacroUtil.callEventHandler( - ON_LOAD_CAMPAIGN_CALLBACK, - lib.getNamespace().get(), - "", - token.get(), - Collections.emptyMap(), - true); - } - } - return null; - }); - return null; - }); + List libTokens = EventMacroUtil.getEventMacroTokens(ON_LOAD_CAMPAIGN_CALLBACK); + String prefix = ON_LOAD_CAMPAIGN_CALLBACK + "@"; + for (Token handler : libTokens) { + EventMacroUtil.callEventHandlerOld( + prefix + handler.getName(), "", handler, Collections.emptyMap(), true); + } } /** diff --git a/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java b/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java index 8b10a7b0c7..6a223e8c56 100644 --- a/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java +++ b/src/main/java/net/rptools/maptool/model/library/token/LibraryToken.java @@ -118,6 +118,16 @@ static boolean handles(URL path) { } } + /** + * Returns the namespace for a lib token. + * + * @param name the name of the lib token. + * @return the namespace for the lib token. + */ + static String namespaceForName(String name) { + return name.substring(4); + } + /** * Creates a new {@code LibraryToken} for the lib:token id. * @@ -127,7 +137,7 @@ static boolean handles(URL path) { LibraryToken(Token token) { id = token.getId(); name = token.getName(); - namespace = token.getName().substring(4); + namespace = namespaceForName(token.getName()); version = Objects.requireNonNullElse( token.getProperty(LIB_VERSION_PROPERTY_NAME), LIB_VERSION_UNKNOWN) diff --git a/src/main/java/net/rptools/maptool/model/library/token/LibraryTokenManager.java b/src/main/java/net/rptools/maptool/model/library/token/LibraryTokenManager.java index 6fe19c3924..084f911497 100644 --- a/src/main/java/net/rptools/maptool/model/library/token/LibraryTokenManager.java +++ b/src/main/java/net/rptools/maptool/model/library/token/LibraryTokenManager.java @@ -102,7 +102,7 @@ public void tokenRemoved(TokensRemovedEvent event) { removeTokens( event.info().stream() .filter(t -> t.name().toLowerCase().startsWith("lib:")) - .map(t -> new LibraryToken(t.token())) + .map(t -> LibraryToken.namespaceForName(t.name())) .toList()); }); } @@ -131,12 +131,8 @@ private void addTokens(Collection libs) { }); } - private void removeTokens(Collection libs) { - libs.forEach( - l -> { - String namespace = l.getNamespace().join(); - libraryTokens.remove(namespace); - }); + private void removeTokens(Collection namespaces) { + namespaces.forEach(libraryTokens::remove); } private void changeTokens(Collection libs) { @@ -145,7 +141,7 @@ private void changeTokens(Collection libs) { // name may have changed so we need to search by id GUID id = l.getId(); var old = libraryTokens.values().stream().filter(l2 -> id.equals(l2.getId())).findFirst(); - old.ifPresent(libraryToken -> removeTokens(List.of(libraryToken))); + old.ifPresent(libraryToken -> removeTokens(List.of(libraryToken.getNamespace().join()))); addTokens(List.of(l)); }); } diff --git a/src/main/java/net/rptools/maptool/model/library/token/TokenLibraryData.java b/src/main/java/net/rptools/maptool/model/library/token/TokenLibraryData.java index c616c71d83..e1525cb669 100644 --- a/src/main/java/net/rptools/maptool/model/library/token/TokenLibraryData.java +++ b/src/main/java/net/rptools/maptool/model/library/token/TokenLibraryData.java @@ -78,12 +78,26 @@ private DataValue getData(String key) { } else if (val instanceof String s) { if (s.trim().startsWith("{") || s.startsWith("[")) { var jsonElement = JsonParser.parseString(s); - if (jsonElement.isJsonArray()) { - return DataValueFactory.fromJsonArray(key, jsonElement.getAsJsonArray()); - } else if (jsonElement.isJsonObject()) { - return DataValueFactory.fromJsonObject(key, jsonElement.getAsJsonObject()); + try { + if (jsonElement.isJsonArray()) { + return DataValueFactory.fromJsonArray(key, jsonElement.getAsJsonArray()); + } else if (jsonElement.isJsonObject()) { + return DataValueFactory.fromJsonObject(key, jsonElement.getAsJsonObject()); + } + } catch (Exception e) { + // Do nothing if the json is invalid } } + try { + double dval = Double.parseDouble(s.trim()); + if (dval == (long) dval) { + return DataValueFactory.fromLong(key, (long) dval); + } else { + return DataValueFactory.fromDouble(key, dval); + } + } catch (NumberFormatException e) { + // Do nothing if can't be parsed as a number + } return DataValueFactory.fromString(key, s); } else { return DataValueFactory.fromString(key, val.toString()); diff --git a/src/main/java/net/rptools/maptool/util/EventMacroUtil.java b/src/main/java/net/rptools/maptool/util/EventMacroUtil.java index e0ee963c43..ab3deda96f 100644 --- a/src/main/java/net/rptools/maptool/util/EventMacroUtil.java +++ b/src/main/java/net/rptools/maptool/util/EventMacroUtil.java @@ -233,4 +233,67 @@ public static MapToolVariableResolver callEventHandler( } return newResolver; } + + /** + * Utility wrapper for running a specified macro as an event handler, getting back the variable + * resolver instance that can be checked for any particular outputs. + * + *

Called macros will output to chat as normal - to suppress, see {@link + * #callEventHandlerOld(String, String, Token, Map, boolean)} + * + * @param macroTarget the fully-qualified macro name + * @param args the argument string to pass + * @param tokenInContext token to set as current, if any + * @param varsToSet any variables that should be initialized in the macro scope + * @return the variable resolver containing the resulting variable states + */ + public static MapToolVariableResolver callEventHandlerOld( + final String macroTarget, + final String args, + final Token tokenInContext, + Map varsToSet) { + return callEventHandlerOld(macroTarget, args, tokenInContext, varsToSet, false); + } + + /** + * Utility wrapper for running a specified macro as an event handler, getting back the variable + * resolver instance that can be checked for any particular outputs. + * + *

Optionally suppresses chat output. + * + * @param macroTarget the fully-qualified macro name + * @param args the argument string to pass + * @param tokenInContext token to set as current, if any + * @param varsToSet any variables that should be initialized in the macro scope + * @param suppressChatOutput whether normal macro chat output should be suppressed + * @return the variable resolver containing the resulting variable states + */ + public static MapToolVariableResolver callEventHandlerOld( + final String macroTarget, + final String args, + final Token tokenInContext, + Map varsToSet, + boolean suppressChatOutput) { + if (varsToSet == null) varsToSet = Collections.emptyMap(); + MapToolVariableResolver newResolver = new MapToolVariableResolver(tokenInContext); + try { + for (Map.Entry entry : varsToSet.entrySet()) { + newResolver.setVariable(entry.getKey(), entry.getValue()); + } + String resultVal = + MapTool.getParser().runMacro(newResolver, tokenInContext, macroTarget, args, false); + if (!suppressChatOutput && resultVal != null && !resultVal.equals("")) { + MapTool.addMessage( + new TextMessage( + TextMessage.Channel.SAY, null, MapTool.getPlayer().getName(), resultVal, null)); + } + } catch (AbortFunctionException afe) { + // Do nothing + } catch (ParserException e) { + MapTool.addLocalMessage( + "Event continuing after error running " + macroTarget + ": " + e.getMessage()); + LOGGER.debug("error running {}: {}", macroTarget, e.getMessage(), e); + } + return newResolver; + } } From 8c28cdf3151d50074e9f72fae516871fab0574c8 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Mon, 15 Nov 2021 01:50:00 +1030 Subject: [PATCH 7/7] remove unwanted file --- .deepsource.toml | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml deleted file mode 100644 index dac4e4f3e1..0000000000 --- a/.deepsource.toml +++ /dev/null @@ -1,26 +0,0 @@ -version = 1 - -[[analyzers]] -name = "python" -enabled = true - - [analyzers.meta] - runtime_version = "3.x.x" - -[[analyzers]] -name = "javascript" -enabled = true - - [analyzers.meta] - plugins = ["react"] - -[[analyzers]] -name = "shell" -enabled = true - -[[analyzers]] -name = "java" -enabled = true - - [analyzers.meta] - runtime_version = "15"