Skip to content

Commit

Permalink
Merge pull request #15 from DarviL82/dev
Browse files Browse the repository at this point in the history
Version 0.2.0 - Megarefactor
  • Loading branch information
darvil82 authored Dec 14, 2023
2 parents 857cb24 + afcc791 commit 45b5dd2
Show file tree
Hide file tree
Showing 91 changed files with 2,069 additions and 2,766 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
branches:
- main

permissions:
contents: write

jobs:
publish:
runs-on: ubuntu-latest
Expand Down
44 changes: 6 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

<br><br>

> [!IMPORTANT]
> **This project is still in development.** It is not recommended to use Lanat in production, as it could possibly
> have important issues. It is also quickly evolving, thus breaking changes are constantly being made.
### Example
- First, we define our Command by creating a *Command Template*.
Expand Down Expand Up @@ -76,41 +79,6 @@ The package is currently available on Repsy and GitHub Packages.
```kotlin
implementation("com.darvil:lanat:+")
```
> [!NOTE]
> The `+` symbol is a wildcard that will automatically use the latest version of the package.
> You can also specify a specific version (e.g. `0.1.0`).

<details>

<summary><strong>Install from Github Packages</strong></summary>

If using Gradle, follow these steps:

1. Authenticate to GitHub Packages to be able to download the package. You can do this by adding the following to your [gradle.properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties) file:

```
gpr.user=USERNAME
gpr.key=PERSONAL_ACCESS_TOKEN
```

Replace `USERNAME` with your GitHub username and `PERSONAL_ACCESS_TOKEN` with a personal access token that has the `read:packages` scope.

2. Add the following inside your `repositories` block:

```kotlin
maven {
url = uri("https://maven.pkg.github.com/darvil82/lanat")
credentials {
username = project.findProperty("gpr.user") as String?
password = project.findProperty("gpr.key") as String?
}
}
```

3. Follow step 2 from the previous section.

This information is available at the [GitHub Packages documentation](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#using-a-published-package).

For other build tools, see [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#using-a-published-package).

</details>
> [!NOTE]
> The `+` symbol is a wildcard that will automatically use the latest version of the package.
> You can also specify a specific version (e.g. `0.1.0`).
12 changes: 8 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ plugins {
}

group = "com.darvil"
version = "0.1.0"
version = "0.2.0"
description = "Command line argument parser"

dependencies {
implementation("com.darvil:utils:0.0.2")
implementation("com.darvil:terminal-text-formatter:0.0.5")

implementation("org.jetbrains:annotations:24.0.1")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
testImplementation(platform("org.junit:junit-bom:5.9.1"))
testImplementation("org.junit.jupiter:junit-jupiter")
}

java {
Expand All @@ -22,6 +25,7 @@ java {

repositories {
mavenCentral()
maven("https://repsy.io/mvn/darvil/java")
}

publishing {
Expand All @@ -46,7 +50,7 @@ publishing {
}
}

tasks.named<Test>("test") {
tasks.test {
useJUnitPlatform()
}

Expand Down
81 changes: 24 additions & 57 deletions src/main/java/lanat/Argument.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
import lanat.argumentTypes.BooleanArgumentType;
import lanat.argumentTypes.DummyArgumentType;
import lanat.exceptions.ArgumentAlreadyExistsException;
import lanat.parsing.errors.CustomError;
import lanat.parsing.errors.ParseError;
import lanat.utils.*;
import lanat.utils.displayFormatter.Color;
import lanat.parsing.errors.Error;
import lanat.parsing.errors.ParseErrors;
import lanat.utils.ErrorCallbacks;
import lanat.utils.ErrorsContainer;
import lanat.utils.Resettable;
import lanat.utils.UtlMisc;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import textFormatter.Color;
import utils.ModifyRecord;
import utils.MultiComparator;
import utils.UtlString;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down Expand Up @@ -68,9 +74,9 @@
* @see ArgumentParser
*/
public class Argument<Type extends ArgumentType<TInner>, TInner>
implements ErrorsContainer<CustomError>,
implements ErrorsContainer<Error.CustomError>,
ErrorCallbacks<TInner,
Argument<Type, TInner>>,
Argument<Type, TInner>>,
Resettable,
CommandUser,
ArgumentGroupUser,
Expand Down Expand Up @@ -388,28 +394,6 @@ public void setRepresentationColor(@NotNull Color color) {
this.representationColor.set(color);
}


/**
* Returns {@code true} if this argument is the help argument of its parent command. This just checks if the
* argument's name is "help" and if it is marked with {@link #setAllowUnique(boolean)}.
*
* @return {@code true} if this argument is the help argument of its parent command.
*/
public boolean isHelpArgument() {
return this.getName().equals("help") && this.isUniqueAllowed();
}

/**
* Pass the specified values array to the argument type to parse it.
*
* @param tokenIndex This is the global index of the token that is currently being parsed. Used when dispatching
* errors.
* @param values The value array that should be parsed.
*/
public void parseValues(short tokenIndex, @NotNull String... values) {
this.argType.parseAndUpdateValue(tokenIndex, values);
}

/**
* This method is called when the command is finished parsing. <strong>And should only ever be called once (per
* parse).</strong>
Expand All @@ -418,15 +402,14 @@ public void parseValues(short tokenIndex, @NotNull String... values) {
*/
public @Nullable TInner finishParsing() {
final TInner finalValue = this.argType.getFinalValue();
final TInner defaultValue = UtlMisc.nonNullOrElse(this.defaultValue, this.argType.getInitialValue());
final TInner defaultValue = this.defaultValue == null ? this.argType.getInitialValue() : null;

/* no, | is not a typo. We don't want the OR operator to short-circuit, we want all of them to be evaluated
* because the methods have side effects (they add errors to the parser) */
TInner returnValue = (finalValue == null | !this.finishParsing$checkExclusivity() | !this.finishParsing$checkUsageCount())
? defaultValue
: finalValue;

this.argType.getErrorsUnderDisplayLevel().forEach(this.parentCommand.getParser()::addError);
if (this.parentGroup != null) this.parentGroup.setArgUsed();

// if the argument type has a value defined (even if it wasn't used), use that. Otherwise, use the default value
Expand All @@ -443,23 +426,15 @@ public void parseValues(short tokenIndex, @NotNull String... values) {

if (usageCount == 0) {
if (this.required && !this.parentCommand.uniqueArgumentReceivedValue(this)) {
this.parentCommand.getParser().addError(
// just show it at the end. doesnt really matter
ParseError.ParseErrorType.REQUIRED_ARGUMENT_NOT_USED, this, 0
);
this.parentCommand.getParser().addError(new ParseErrors.RequiredArgumentNotUsedError(this));
}
return false;
}

// make sure that the argument was used the minimum number of times specified
if (!this.argType.getRequiredUsageCount().isInRangeInclusive(usageCount)) {
if (!this.argType.getRequiredUsageCount().containsInclusive(usageCount)) {
this.parentCommand.getParser()
.addError(
ParseError.ParseErrorType.ARG_INCORRECT_USAGES_COUNT,
this,
this.argType.getLastReceivedValuesNum(),
this.argType.getLastTokenIndex()
);
.addError(new ParseErrors.IncorrectUsagesCountError(this.argType.getLastTokensIndicesPair(), this));
return false;
}

Expand All @@ -479,17 +454,9 @@ public void parseValues(short tokenIndex, @NotNull String... values) {
ArgumentGroup exclusivityResult = this.parentGroup.checkExclusivity(null);
if (exclusivityResult == null) return true;

this.parentCommand.getParser().addError(
new ParseError(
ParseError.ParseErrorType.MULTIPLE_ARGS_IN_EXCLUSIVE_GROUP_USED,
this.argType.getLastTokenIndex(),
this,
this.argType.getLastReceivedValuesNum()
)
{{
this.setArgumentGroup(exclusivityResult);
}}
);
this.parentCommand.getParser().addError(new ParseErrors.MultipleArgsInExclusiveGroupUsedError(
this.argType.getLastTokensIndicesPair(), exclusivityResult
));
return false;
}

Expand Down Expand Up @@ -590,7 +557,7 @@ public static int compareByPriority(@NotNull Argument<?, ?> first, @NotNull Argu
* @return the sorted list
* @see #compareByPriority(Argument, Argument)
*/
public static List<Argument<?, ?>> sortByPriority(@NotNull List<@NotNull Argument<?, ?>> args) {
public static @NotNull List<Argument<?, ?>> sortByPriority(@NotNull List<@NotNull Argument<?, ?>> args) {
return new ArrayList<>(args) {{
this.sort(Argument::compareByPriority);
}};
Expand Down Expand Up @@ -705,23 +672,23 @@ private PrefixChar(char character) {
// just act as a proxy to the type error handling

@Override
public @NotNull List<@NotNull CustomError> getErrorsUnderExitLevel() {
public @NotNull List<Error.@NotNull CustomError> getErrorsUnderExitLevel() {
return this.argType.getErrorsUnderExitLevel();
}

@Override
public @NotNull List<@NotNull CustomError> getErrorsUnderDisplayLevel() {
public @NotNull List<Error.@NotNull CustomError> getErrorsUnderDisplayLevel() {
return this.argType.getErrorsUnderDisplayLevel();
}

@Override
public boolean hasExitErrors() {
return this.argType.hasExitErrors() || !this.getErrorsUnderExitLevel().isEmpty();
return this.argType.hasExitErrors();
}

@Override
public boolean hasDisplayErrors() {
return this.argType.hasDisplayErrors() || !this.getErrorsUnderDisplayLevel().isEmpty();
return this.argType.hasDisplayErrors();
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/lanat/ArgumentBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import lanat.argumentTypes.DummyArgumentType;
import lanat.exceptions.ArgumentTypeInferException;
import lanat.utils.UtlReflection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import utils.UtlReflection;

import java.lang.reflect.Field;
import java.util.Arrays;
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/lanat/ArgumentGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import lanat.exceptions.ArgumentGroupAlreadyExistsException;
import lanat.utils.Resettable;
import lanat.utils.UtlString;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import utils.UtlString;

import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -258,6 +258,10 @@ public void resetState() {
return this.name;
}

/**
* Sets the description of this group. The description is used to be displayed in the help message.
* @param description The description of this group.
*/
public void setDescription(@NotNull String description) {
this.description = description;
}
Expand Down
Loading

0 comments on commit 45b5dd2

Please sign in to comment.