Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions bom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# CommandsAPI BOM (Bill of Materials)

This module provides a BOM (Bill of Materials) for CommandsAPI, making it easier to manage consistent versions across all CommandsAPI modules.

## Usage

### Gradle (Kotlin DSL)

```kotlin
dependencies {
// Import the BOM
implementation(platform("fr.traqueur.commands:bom:VERSION"))

// Then add dependencies without specifying versions
implementation("fr.traqueur.commands:core")
implementation("fr.traqueur.commands:platform-spigot")
implementation("fr.traqueur.commands:platform-velocity")
implementation("fr.traqueur.commands:platform-jda")
implementation("fr.traqueur.commands:annotations-addon")
}
```

### Gradle (Groovy DSL)

```groovy
dependencies {
// Import the BOM
implementation platform('fr.traqueur.commands:bom:VERSION')

// Then add dependencies without specifying versions
implementation 'fr.traqueur.commands:core'
implementation 'fr.traqueur.commands:platform-spigot'
implementation 'fr.traqueur.commands:platform-velocity'
implementation 'fr.traqueur.commands:platform-jda'
implementation 'fr.traqueur.commands:annotations-addon'
}
```

### Maven

```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>fr.traqueur.commands</groupId>
<artifactId>bom</artifactId>
<version>VERSION</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<!-- Then add dependencies without specifying versions -->
<dependency>
<groupId>fr.traqueur.commands</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>fr.traqueur.commands</groupId>
<artifactId>platform-spigot</artifactId>
</dependency>
<dependency>
<groupId>fr.traqueur.commands</groupId>
<artifactId>platform-velocity</artifactId>
</dependency>
<dependency>
<groupId>fr.traqueur.commands</groupId>
<artifactId>platform-jda</artifactId>
</dependency>
<dependency>
<groupId>fr.traqueur.commands</groupId>
<artifactId>annotations-addon</artifactId>
</dependency>
</dependencies>
```

## Benefits

Using the BOM provides several advantages:

1. **Version Consistency**: All CommandsAPI modules will use compatible versions
2. **Simplified Dependency Management**: No need to specify versions for each module
3. **Easier Updates**: Update all modules by changing only the BOM version
4. **Reduced Conflicts**: Ensures all modules work together correctly

## Available Modules

The BOM manages versions for the following modules:

- `core` - Core functionality and API
- `platform-spigot` - Spigot/Bukkit platform support
- `platform-velocity` - Velocity proxy platform support
- `platform-jda` - JDA (Discord) platform support
- `annotations-addon` - Annotation-based command registration
77 changes: 77 additions & 0 deletions bom/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
plugins {
id 'java-platform'
id 'maven-publish'
}

description = 'CommandsAPI BOM (Bill of Materials)'

javaPlatform {
allowDependencies()
}

dependencies {
constraints {
api(project(':core'))
api(project(':spigot'))
api(project(':velocity'))
api(project(':jda'))
api(project(':annotations-addon'))
}
}

publishing {
repositories {
maven {
def repository = System.getProperty('repository.name', 'snapshots')
def repoType = repository.toLowerCase()

name = "groupez${repository.capitalize()}"
url = uri("https://repo.groupez.dev/${repoType}")

credentials {
username = findProperty("${name}Username") ?: System.getenv('MAVEN_USERNAME')
password = findProperty("${name}Password") ?: System.getenv('MAVEN_PASSWORD')
}

authentication {
create("basic", BasicAuthentication)
}
}
}

publications {
create('maven', MavenPublication) {
from components.javaPlatform

groupId = rootProject.group.toString()
artifactId = 'bom'
version = rootProject.version.toString()

pom {
name = 'CommandsAPI BOM'
description = 'CommandsAPI Bill of Materials - Manages consistent versions across CommandsAPI modules'
url = 'https://github.com/Traqueur-dev/CommandsAPI'

licenses {
license {
name = 'MIT License'
url = 'https://opensource.org/licenses/MIT'
}
}

developers {
developer {
id = 'traqueur'
name = 'Traqueur'
}
}

scm {
connection = 'scm:git:git://github.com/Traqueur-dev/CommandsAPI.git'
developerConnection = 'scm:git:ssh://github.com/Traqueur-dev/CommandsAPI.git'
url = 'https://github.com/Traqueur-dev/CommandsAPI'
}
}
}
}
}
8 changes: 5 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ allprojects {
group = 'fr.traqueur.commands'
version = property('version')

apply {
plugin 'java-library'
if (project.name != 'bom') {
apply {
plugin 'java-library'
}
}

ext.classifier = System.getProperty('archive.classifier')
Expand All @@ -27,7 +29,7 @@ allprojects {
}

subprojects {
if (project.name.contains('test-')) {
if (project.name.contains('test-') || project.name == 'bom') {
return;
}

Expand Down
23 changes: 16 additions & 7 deletions core/src/main/java/fr/traqueur/commands/api/CommandManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public abstract class CommandManager<T, S> {
/**
* The argument converters registered in the command manager.
*/
private final Map<String, ArgumentConverter.Wrapper<?>> typeConverters;
private final Map<Class<?>, ArgumentConverter.Wrapper<?>> typeConverters;

/**
* The tab completer registered in the command manager.
Expand Down Expand Up @@ -202,7 +202,7 @@ public void unregisterCommand(Command<T, S> command, boolean subcommands) {
* @param <C> The type of the argument.
*/
public <C> void registerConverter(Class<C> typeClass, ArgumentConverter<C> converter) {
this.typeConverters.put(typeClass.getSimpleName().toLowerCase(), new ArgumentConverter.Wrapper<>(typeClass, converter));
this.typeConverters.put(typeClass, new ArgumentConverter.Wrapper<>(typeClass, converter));
}

/**
Expand Down Expand Up @@ -251,8 +251,8 @@ public Map<String, Map<Integer, TabCompleter<S>>> getCompleters() {
* @param type The type to check.
* @return true if a TabCompleter is registered for this type.
*/
public boolean hasTabCompleterForType(String type) {
ArgumentConverter.Wrapper<?> wrapper = this.typeConverters.get(type.toLowerCase());
public boolean hasTabCompleterForType(Class<?> type) {
ArgumentConverter.Wrapper<?> wrapper = this.typeConverters.get(type);
return wrapper != null && wrapper.converter() instanceof TabCompleter;
}

Expand All @@ -263,8 +263,8 @@ public boolean hasTabCompleterForType(String type) {
* @return The TabCompleter for this type, or null if none exists.
*/
@SuppressWarnings("unchecked")
public TabCompleter<S> getTabCompleterForType(String type) {
ArgumentConverter.Wrapper<?> wrapper = this.typeConverters.get(type.toLowerCase());
public TabCompleter<S> getTabCompleterForType(Class<?> type) {
ArgumentConverter.Wrapper<?> wrapper = this.typeConverters.get(type);
if (wrapper != null && wrapper.converter() instanceof TabCompleter) {
return (TabCompleter<S>) wrapper.converter();
}
Expand Down Expand Up @@ -411,7 +411,7 @@ private void addCompletionsForLabel(String[] labelParts) {
private void addCompletionForArgs(String label, int commandSize, List<Argument<S>> args) {
for (int i = 0; i < args.size(); i++) {
Argument<S> arg = args.get(i);
String type = arg.type().key();
Class<?> type = arg.type().key();
ArgumentConverter.Wrapper<?> entry = this.typeConverters.get(type);
TabCompleter<S> argConverter = arg.tabCompleter();
if (argConverter != null) {
Expand Down Expand Up @@ -465,9 +465,18 @@ public CommandInvoker<T, S> getInvoker() {
*/
private void registerInternalConverters() {
this.registerConverter(String.class, (s) -> s);

// Register both primitive and wrapper types for DefaultArgumentParser (Spigot/Velocity).
// JDA's ArgumentParser handles primitives internally, but text-based platforms need explicit registration.
// Wrapper types (Integer.class, Long.class, etc.) are registered for compatibility with wrapper usage.
// Primitive types (int.class, long.class, etc.) are registered to support primitive method parameters.
this.registerConverter(Boolean.class, new BooleanArgument<>());
this.registerConverter(boolean.class, new BooleanArgument<>());
this.registerConverter(Integer.class, new IntegerArgument());
this.registerConverter(int.class, new IntegerArgument());
this.registerConverter(Double.class, new DoubleArgument());
this.registerConverter(double.class, new DoubleArgument());
this.registerConverter(Long.class, new LongArgument());
this.registerConverter(long.class, new LongArgument());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Argument(String name, ArgumentType type) {
}

public String canonicalName() {
return this.name + ":" + this.type.key();
return this.name + ":" + this.type.key().getSimpleName().toLowerCase();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ static ArgumentType of(Class<?> clazz) {
return new Simple(clazz);
}

String key();
Class<?> key();

/**
* Check if this is the infinite type.
Expand All @@ -23,8 +23,8 @@ default boolean isInfinite() {
record Simple(Class<?> clazz) implements ArgumentType {

@Override
public String key() {
return clazz.getSimpleName().toLowerCase();
public Class<?> key() {
return clazz;
}

}
Expand All @@ -33,8 +33,8 @@ record Infinite() implements ArgumentType {
public static final Infinite INSTANCE = new Infinite();

@Override
public String key() {
return "infinite";
public Class<?> key() {
return fr.traqueur.commands.api.arguments.Infinite.class;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public class DefaultArgumentParser<T, S> implements ArgumentParser<T, S, String[

private static final int MAX_INFINITE_LENGTH = 10_000;

private final Map<String, ArgumentConverter.Wrapper<?>> typeConverters;
private final Map<Class<?>, ArgumentConverter.Wrapper<?>> typeConverters;
private final Logger logger;

public DefaultArgumentParser(Map<String, ArgumentConverter.Wrapper<?>> typeConverters, Logger logger) {
public DefaultArgumentParser(Map<Class<?>, ArgumentConverter.Wrapper<?>> typeConverters, Logger logger) {
this.typeConverters = typeConverters;
this.logger = logger;
}
Expand Down Expand Up @@ -80,15 +80,15 @@ public ParseResult parse(Command<T, S> command, String[] rawArgs) {
}

private ParseResult parseSingle(Arguments arguments, Argument<S> arg, String input) {
String typeKey = arg.type().key();
Class<?> typeKey = arg.type().key();
ArgumentConverter.Wrapper<?> wrapper = typeConverters.get(typeKey);

if (wrapper == null) {
return ParseResult.error(new ParseError(
ParseError.Type.TYPE_NOT_FOUND,
arg.name(),
input,
"No converter for type: " + typeKey
"No converter for type: " + typeKey.getSimpleName()
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ class DefaultArgumentParserTest {

@BeforeEach
void setUp() {
Map<String, ArgumentConverter.Wrapper<?>> converters = new HashMap<>();
converters.put("string", new ArgumentConverter.Wrapper<>(String.class, s -> s));
converters.put("integer", new ArgumentConverter.Wrapper<>(Integer.class, s -> {
Map<Class<?>, ArgumentConverter.Wrapper<?>> converters = new HashMap<>();
converters.put(String.class, new ArgumentConverter.Wrapper<>(String.class, s -> s));
converters.put(Integer.class, new ArgumentConverter.Wrapper<>(Integer.class, s -> {
try {
return Integer.valueOf(s);
} catch (NumberFormatException e) {
return null;
}
}));
converters.put("double", new ArgumentConverter.Wrapper<>(Double.class, s -> {
converters.put(Double.class, new ArgumentConverter.Wrapper<>(Double.class, s -> {
try {
return Double.valueOf(s);
} catch (NumberFormatException e) {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=5.0.0
version=5.0.1
Loading
Loading