Skip to content

Commit

Permalink
Merge pull request #41241 from gayaldassanayake/tool-u8-compat
Browse files Browse the repository at this point in the history
Update help texts and make update 7 bal-tools.toml compatible with update 8
  • Loading branch information
azinneera committed Aug 18, 2023
2 parents e6f3165 + 0a7c088 commit b257616
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ private static Optional<BLauncherCmd> getInvokedCmd(String... args) {
}

private static ServiceLoader<BLauncherCmd> loadAdditionalCommands(String ...args) {
BalToolsUtil.updateOldBalToolsToml();
if (null != args && args.length > 0 && BalToolsUtil.isToolCommand(args[0])) {
String commandName = args[0];
BalToolsUtil.addToolIfCommandIsABuiltInTool(commandName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import io.ballerina.cli.launcher.LauncherUtils;
import io.ballerina.projects.BalToolsManifest;
import io.ballerina.projects.BalToolsToml;
import io.ballerina.projects.PackageVersion;
import io.ballerina.projects.ProjectException;
import io.ballerina.projects.SemanticVersion;
import io.ballerina.projects.internal.BalToolsManifestBuilder;
import io.ballerina.projects.internal.BalaFiles;
Expand All @@ -40,6 +42,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -115,6 +118,9 @@ public class BalToolsUtil {

private static final Path balToolsTomlPath = Path.of(
System.getProperty(CommandUtil.USER_HOME), HOME_REPO_DEFAULT_DIRNAME, CONFIG_DIR, BAL_TOOLS_TOML);
private static Path balaCacheDirPath = ProjectUtils.createAndGetHomeReposPath()
.resolve(REPOSITORIES_DIR).resolve(CENTRAL_REPOSITORY_CACHE_NAME)
.resolve(ProjectConstants.BALA_DIR_NAME);

public static boolean isNonBuiltInToolCommand(String commandName) {
return isToolCommand(commandName) && !builtInToolCommands.contains(commandName);
Expand Down Expand Up @@ -231,4 +237,59 @@ private static List<File> findJarFiles(File directory) {
}
return jarFiles;
}

/**
* Update the bal-tools.toml file with the version and the active flags.
* bal-tools.tomls of updates 6, 7 only has id, name and org fields. Therefore, we need to update the
* bal-tools.toml file when the user moves from updates 6, 7 to update 8 and above.
*/
public static void updateOldBalToolsToml() {
BalToolsToml balToolsToml = BalToolsToml.from(balToolsTomlPath);
BalToolsManifestBuilder balToolsManifestBuilder = BalToolsManifestBuilder.from(balToolsToml);
BalToolsManifest balToolsManifest = balToolsManifestBuilder.build();
Map<String, BalToolsManifestBuilder.OldTool> oldTools = balToolsManifestBuilder.getOldTools();
if (oldTools.isEmpty()) {
return;
}
oldTools.values().stream().forEach(tool -> {
Path toolCachePath = balaCacheDirPath.resolve(Path.of(tool.org(), tool.name()));
if (toolCachePath.toFile().isDirectory()) {
List<String> versions = Arrays.stream(toolCachePath.toFile().listFiles((dir, name) -> {
try {
PackageVersion.from(name);
return true;
} catch (ProjectException ignore) {
return false;
}
})).map(File::getName).collect(Collectors.toList());

Optional<String> latestVersion = getLatestVersion(versions);
versions.stream().forEach(version -> {
// If there is no current active version in balToolsManifest, we set the latest version in the
// central cache as active. This is because in U6, U7, the latest is automatically picked as active.
boolean isActive = balToolsManifest.getActiveTool(tool.id()).isEmpty()
&& latestVersion.isPresent()
&& latestVersion.get().equals(version);
if (balToolsManifest.getTool(tool.id(), version).isEmpty()) {
balToolsManifest.addTool(tool.id(), tool.org(), tool.name(), version, isActive);
}
});
}
});
balToolsToml.modify(balToolsManifest);
}

private static Optional<String> getLatestVersion(List<String> versions) {
return versions.stream().map(SemanticVersion::from)
.max((v1, v2) -> {
if (v1.greaterThan(v2)) {
return 1;
} else if (v2.greaterThan(v1)) {
return -1;
} else {
return 0;
}
})
.map(SemanticVersion::toString);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ COMMANDS
test Run package tests
doc Generate current package's documentation
pack Create distribution format of the current package
tool Manage Ballerina tools

Package Commands:
new Create a new Ballerina package
Expand All @@ -50,4 +49,5 @@ COMMANDS
persist Manage data persistence
bindgen Generate the Ballerina bindings for Java APIs
shell Run Ballerina interactive REPL [Experimental]
tool Manage Ballerina CLI tools
version Print the Ballerina version
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
NAME
ballerina-tool-list - List all the tools available in the bal tool chain
ballerina-tool-list - List all tools available in the local environment.

SYNOPSIS
bal tool list
Expand All @@ -9,7 +9,6 @@ OPTIONS
Print the usage details of tool list command.

DESCRIPTION
List the tool-id and the version of all locally available tools.
List the tool-id and the versions of all locally available tools.

When multiple versions of the same tool exist, the latest version
will be listed.
The active tool version is marked with an asterisk (*).
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
NAME
ballerina-tool-pull - Pull a given tool from Ballerina Central
ballerina-tool-pull - Pull a tool from the Ballerina Central

SYNOPSIS
bal tool pull <tool-id>[:<version>]
Expand All @@ -9,12 +9,10 @@ OPTIONS
Print the usage details of tool pull command.

DESCRIPTION
Fetch a given tool from Ballerina Central repository and install it
as a command in the bal tool chain.

If the tool version is specified, that specific version will be fetched.
If the tool version is not specified, the latest version will be
fetched.
Fetch a given tool from the Ballerina Central and install it
as a Ballerina CLI command.

The specified tool version should be compatible with the current
distribution version.
distribution version. If the tool version is not specified,
the latest version compatible with the current distribution
will be fetched.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
NAME
ballerina-tool-remove - Remove a given bal tool from the bal tool chain
ballerina-tool-remove - Remove a tool from the local environment.

SYNOPSIS
bal tool remove <tool-id>[:<version>]
Expand All @@ -9,10 +9,10 @@ OPTIONS
Print the usage details of tool remove command.

DESCRIPTION
Remove an already installed tool from the bal tool chain.
Remove a tool that was installed into to the local environment.

If the tool version is specified, that specific version will be removed.
If the version is not specified, all versions of the tool will be
removed.

The active version of a tool cannot be removed.

If the version is not specified, all versions of the tool will be
removed including the active version.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
NAME
ballerina-tool-search - Search Ballerina Central for bal-tools
ballerina-tool-search - Search the Ballerina Central for tools

SYNOPSIS
bal tool search [<tool-id>|<text>]
Expand All @@ -9,7 +9,7 @@ OPTIONS
Print the usage details of tool search command.

DESCRIPTION
Search Ballerina Central repository for bal-tools using a tool-id.
Search the Ballerina Central for tools using a tool-id.

EXAMPLES
Search by tool id.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NAME
ballerina-tool-update - Update to the latest compatible version of the
currently active tool version
ballerina-tool-update - Update a tool to the latest version compatible
with the current distribution.

SYNOPSIS
bal tool update <tool-id>
Expand All @@ -10,5 +10,6 @@ OPTIONS
Print the usage details of tool the update command.

DESCRIPTION
Fetch the latest compatible version of a given tool from Ballerina
Central repository and set it as the active version.
Fetch the latest version of a given tool that is compatible
with the current distribution from the Ballerina Central
repository and set it as the active version.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
NAME
ballerina-tool-use - Mark a version of a tool as the active version
ballerina-tool-use - Set a tool version as the active version.

SYNOPSIS
bal tool use <tool-id>:<version>
Expand All @@ -9,8 +9,8 @@ OPTIONS
Print the usage details of tool use command.

DESCRIPTION
Mark a specified version of a locally available tool as the active
version.
Mark a specified version of a tool available in the local
environment as the active version.

The active version of a tool is used when the tool is invoked.

Expand Down
37 changes: 18 additions & 19 deletions cli/ballerina-cli/src/main/resources/cli-help/ballerina-tool.help
Original file line number Diff line number Diff line change
@@ -1,56 +1,55 @@
NAME
ballerina-tool - Manage the tools provided by Ballerina
ballerina-tool - Extend the Ballerina CLI with custom commands.

SYNOPSIS
bal tool <command> [<-h> |<--help>]
bal tool <command> [args]

DESCRIPTION
Manage Ballerina command line tools via bal tool chain.
Register and manage custom commands for the Ballerina CLI.

Facilitate pulling tools from Ballerina Central and removing
previously pulled tools.
This command facilitates searching, pulling, and updating tools from the
Ballerina Central, switching between installed versions, and listing and
removing installed tools.

Provide subcommands to list all the locally available tools and search
for tools that are available in Ballerina Central.

OPTIONS
-h, --help
Print the usage details of all tool commands.

TOOL COMMANDS
SUBCOMMANDS
The following is a list of available subcommands:

pull Pull a tool from Ballerina Central.
pull Pull a tool from the Ballerina Central.
remove Remove a tool from the local environment.
update Update a tool to the latest compatible version.
update Update a tool to the latest version.
use Set a tool version as the active version.
list List all tools in the local environment.
search Search Ballerina Central for tools.
list List all tools available in the local environment.
search Search the Ballerina Central for tools.

EXAMPLES
Pull a tool from Ballerina Central.
Pull a tool from the Ballerina Central.
$ bal tool pull health

Pull a specific version of a tool from Ballerina Central.
Pull a specific version of a tool from the Ballerina Central.
$ bal tool pull health:1.0.0

Remove a specific version of previously pulled tool.
Remove a specific version of an installed tool.
$ bal tool remove health:1.0.0

Remove all the versions of a previously pulled tool.
Remove all the versions of an installed tool.
$ bal tool remove health

Update a tool to the latest patch version.
Update a tool to the latest version compatible with the current distribution.
$ bal tool update health

Change the active version of a tool.
$ bal tool use health:1.0.0

List all tools available locally.
List all tools available in the local environment.
$ bal tool list

Search Ballerina Central for tools.
Search the Ballerina Central for tools.
$ bal tool search health

Use 'bal tool <command> --help' for more information on a specific command.
Use 'bal tool <subcommand> --help' for more information on a specific tool subcommand.
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@
*/
public class BalToolsManifestBuilder {
private final Optional<TomlDocument> balToolsToml;

private final BalToolsManifest balToolsManifest;
private final Map<String, OldTool> oldTools;

private BalToolsManifestBuilder(TomlDocument balToolsToml) {
oldTools = new HashMap();
this.balToolsToml = Optional.ofNullable(balToolsToml);
this.balToolsManifest = parseAsBalToolsManifest();
}
Expand All @@ -69,6 +70,10 @@ public BalToolsManifest getBalToolsManifest() {
return balToolsManifest;
}

public Map<String, OldTool> getOldTools() {
return oldTools;
}

public BalToolsManifestBuilder removeTool(String id) {
balToolsManifest.removeTool(id);
return this;
Expand Down Expand Up @@ -122,10 +127,15 @@ private Map<String, Map<String, BalToolsManifest.Tool>> getTools() {
String org = getStringValueFromToolNode(toolNode, "org");
String name = getStringValueFromToolNode(toolNode, "name");
String version = getStringValueFromToolNode(toolNode, "version");
boolean active = getBooleanFromTemplateNode(toolNode, "active");
Optional<Boolean> active = getBooleanFromToolNode(toolNode, "active");

// If id, org or name, one of the value is null, ignore tool record
if (id == null || org == null || name == null || version == null) {
if (id == null || org == null || name == null) {
continue;
}

if (version == null || active.isEmpty()) {
oldTools.put(id, new OldTool(id, org, name));
continue;
}

Expand All @@ -138,7 +148,7 @@ private Map<String, Map<String, BalToolsManifest.Tool>> getTools() {
if (!tools.containsKey(id)) {
tools.put(id, new HashMap<>());
}
tools.get(id).put(version, new BalToolsManifest.Tool(id, org, name, version, active));
tools.get(id).put(version, new BalToolsManifest.Tool(id, org, name, version, active.get()));
}
}
return tools;
Expand All @@ -152,24 +162,36 @@ private String getStringValueFromToolNode(TomlTableNode pkgNode, String key) {
return getStringFromTomlTableNode(topLevelNode);
}

boolean getBooleanFromTemplateNode(TomlTableNode tableNode, String key) {
Optional<Boolean> getBooleanFromToolNode(TomlTableNode tableNode, String key) {
TopLevelNode topLevelNode = tableNode.entries().get(key);
if (topLevelNode == null || topLevelNode.kind() == TomlType.NONE) {
return false;
return Optional.empty();
}

if (topLevelNode.kind() == TomlType.KEY_VALUE) {
TomlKeyValueNode keyValueNode = (TomlKeyValueNode) topLevelNode;
TomlValueNode value = keyValueNode.value();
if (value.kind() == TomlType.BOOLEAN) {
TomlBooleanValueNode tomlBooleanValueNode = (TomlBooleanValueNode) value;
return tomlBooleanValueNode.getValue();
return Optional.ofNullable(tomlBooleanValueNode.getValue());
}
}
return false;
return Optional.empty();
}

public BalToolsManifest build() {
return this.balToolsManifest;
}

/**
* Represents a tool saved in an older update 6 and 7 bal-tools.toml.
* The tool record in the older bal-tools.toml file does not contain the version and active fields.
* @param id tool id
* @param org tool org
* @param name tool name
*
* @since 2201.8.0
*/
public record OldTool(String id, String org, String name) {
}
}
Loading

0 comments on commit b257616

Please sign in to comment.