diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..633ecee --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,73 @@ +name: CI/CD Pipeline + +on: + push: + branches: + - '**' # Runs for all branches + workflow_dispatch: + +jobs: + build: + name: Build & Test + runs-on: ubuntu-latest + if: github.ref != 'refs/heads/master' # Runs on all branches except master + permissions: + contents: read + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Make Maven wrapper executable + run: chmod +x mvnw + + - name: Build and Run Tests + run: ./mvnw --no-transfer-progress clean verify + + - if: ${{ github.ref == 'refs/heads/master' }} + name: Publish to GitHub Packages Apache Maven + run: ./mvnw deploy -s $GITHUB_WORKSPACE/settings.xml + env: + GITHUB_TOKEN: ${{ github.token }} + + deploy: + name: Build, Test & Deploy + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' # Runs only on master + permissions: + contents: read + packages: write # Needed to publish to GitHub Packages + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + cache: 'maven' + + - name: Build and Deploy to GitHub Packages + run: ./mvnw --no-transfer-progress clean deploy -s $GITHUB_WORKSPACE/settings.xml + env: + GITHUB_TOKEN: ${{ github.token }} + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ env.VERSION }} + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.run/All Unit Tests.run.xml b/.run/All Unit Tests.run.xml new file mode 100644 index 0000000..ab3d792 --- /dev/null +++ b/.run/All Unit Tests.run.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 32ad84d..0296be5 100644 --- a/pom.xml +++ b/pom.xml @@ -2,51 +2,99 @@ 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.4.3 - - + com.amalvadkar am-commons-utils 0.0.1-SNAPSHOT + jar am-commons-utils - Common Utilities - - - - - - - - - - - - - + Common Utility Library + + 21 + 5.10.2 + 3.25.3 + + + 3.11.0 + 3.2.5 + 3.3.0 + 3.0.0-M1 + + + + github + GitHub Packages + https://maven.pkg.github.com/abhishekmalvadkar/${project.artifactId} + + + + + - org.springframework.boot - spring-boot-starter + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + - org.springframework.boot - spring-boot-starter-test + org.assertj + assertj-core + ${assertj-core.version} test + + ${project.artifactId} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + false + + + + - org.springframework.boot - spring-boot-maven-plugin + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} diff --git a/src/main/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplication.java b/src/main/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplication.java deleted file mode 100644 index 3509f1c..0000000 --- a/src/main/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.amalvadkar.commons.utils; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class AmCommonsUtilsApplication { - - public static void main(String[] args) { - SpringApplication.run(AmCommonsUtilsApplication.class, args); - } - -} diff --git a/src/main/java/com/amalvadkar/commons/utils/constants/StringConstants.java b/src/main/java/com/amalvadkar/commons/utils/constants/StringConstants.java new file mode 100644 index 0000000..1f3d27d --- /dev/null +++ b/src/main/java/com/amalvadkar/commons/utils/constants/StringConstants.java @@ -0,0 +1,11 @@ +package com.amalvadkar.commons.utils.constants; + +public class StringConstants { + + public static final String EMPTY_STRING = ""; + + private StringConstants() { + throw new UnsupportedOperationException("Constants class"); + } + +} diff --git a/src/main/java/com/amalvadkar/commons/utils/exceptions/InvalidStringException.java b/src/main/java/com/amalvadkar/commons/utils/exceptions/InvalidStringException.java new file mode 100644 index 0000000..25bd7f9 --- /dev/null +++ b/src/main/java/com/amalvadkar/commons/utils/exceptions/InvalidStringException.java @@ -0,0 +1,10 @@ +package com.amalvadkar.commons.utils.exceptions; + +/** + * Custom exception for invalid string operations. + */ +public class InvalidStringException extends RuntimeException { + public InvalidStringException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/amalvadkar/commons/utils/string/StringUtils.java b/src/main/java/com/amalvadkar/commons/utils/string/StringUtils.java new file mode 100644 index 0000000..5e041d4 --- /dev/null +++ b/src/main/java/com/amalvadkar/commons/utils/string/StringUtils.java @@ -0,0 +1,71 @@ +package com.amalvadkar.commons.utils.string; + +import com.amalvadkar.commons.utils.constants.StringConstants; +import com.amalvadkar.commons.utils.exceptions.InvalidStringException; + +/** + * Utility class for common string operations. + */ +public final class StringUtils { + + private StringUtils() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Capitalizes the first letter of the input string. + * + * @param input The string to capitalize. + * @return Capitalized string or an empty string if input is null/empty. + * @throws InvalidStringException if the input is null or empty. + */ + public static String capitalize(String input) { + if (isEmpty(input)) { + throw new InvalidStringException("Input string cannot be null or empty."); + } + return input.substring(0, 1).toUpperCase() + input.substring(1); + } + + /** + * Checks if a string is null or empty. + * + * @param input The string to check. + * @return True if the string is null or empty, otherwise false. + */ + public static boolean isEmpty(String input) { + return input == null || input.trim().isEmpty(); + } + + /** + * Reverses a given string. + * + * @param input The string to reverse. + * @return The reversed string. + */ + public static String reverse(String input) { + if (isEmpty(input)) { + return StringConstants.EMPTY_STRING; + } + return new StringBuilder(input).reverse().toString(); + } + + /** + * Trims spaces from both ends of the string. + * + * @param input The string to trim. + * @return The trimmed string. + */ + public static String trim(String input) { + return isEmpty(input) ? StringConstants.EMPTY_STRING : input.trim(); + } + + /** + * Checks if a string contains only letters. + * + * @param input The string to check. + * @return True if the string contains only letters, otherwise false. + */ + public static boolean containsOnlyLetters(String input) { + return !isEmpty(input) && input.matches("[a-zA-Z]+"); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index e255222..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=am-commons-utils diff --git a/src/test/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplicationTests.java b/src/test/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplicationTests.java deleted file mode 100644 index 4aa48e4..0000000 --- a/src/test/java/com/amalvadkar/commons/utils/AmCommonsUtilsApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.amalvadkar.commons.utils; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class AmCommonsUtilsApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/com/amalvadkar/commons/utils/string/StringUtilsTest.java b/src/test/java/com/amalvadkar/commons/utils/string/StringUtilsTest.java new file mode 100644 index 0000000..7d0e53b --- /dev/null +++ b/src/test/java/com/amalvadkar/commons/utils/string/StringUtilsTest.java @@ -0,0 +1,59 @@ +package com.amalvadkar.commons.utils.string; + +import com.amalvadkar.commons.utils.exceptions.InvalidStringException; +import common.AbstractUnitTest; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class StringUtilsTest extends AbstractUnitTest { + + @Test + void capitalize_should_capitalize_first_letter() { + assertThat(StringUtils.capitalize("hello")).isEqualTo("Hello"); + } + + @Test + void capitalize_should_throw_exception_when_input_is_null() { + assertThatThrownBy(() -> StringUtils.capitalize(null)) + .isInstanceOf(InvalidStringException.class) + .hasMessage("Input string cannot be null or empty."); + } + + @Test + void is_empty_should_return_true_when_string_is_empty() { + assertThat(StringUtils.isEmpty("")).isTrue(); + } + + @Test + void is_empty_should_return_false_when_string_is_not_empty() { + assertThat(StringUtils.isEmpty("test")).isFalse(); + } + + @Test + void reverse_should_return_reversed_string() { + assertThat(StringUtils.reverse("hello")).isEqualTo("olleh"); + } + + @Test + void reverse_should_return_empty_when_input_is_empty() { + assertThat(StringUtils.reverse("")).isEqualTo(""); + } + + @Test + void trim_should_remove_leading_and_trailing_spaces() { + assertThat(StringUtils.trim(" hello ")).isEqualTo("hello"); + } + + @Test + void contains_only_letters_should_return_true_when_only_letters() { + assertThat(StringUtils.containsOnlyLetters("Hello")).isTrue(); + } + + @Test + void contains_only_letters_should_return_false_when_contains_numbers() { + assertThat(StringUtils.containsOnlyLetters("Hello123")).isFalse(); + } + +} \ No newline at end of file diff --git a/src/test/java/common/AbstractUnitTest.java b/src/test/java/common/AbstractUnitTest.java new file mode 100644 index 0000000..e134db1 --- /dev/null +++ b/src/test/java/common/AbstractUnitTest.java @@ -0,0 +1,7 @@ +package common; + +import org.junit.jupiter.api.Tag; + +@Tag("unit") +public class AbstractUnitTest { +}