Compare commits

...

3 commits

Author SHA1 Message Date
85507a1e06 Minor cleanup 2023-09-25 03:19:39 -07:00
d0aa48dbee Added config builder. Closes #3 2023-09-25 03:19:16 -07:00
aaed5f45ce Updated dependencies 2023-09-25 00:46:20 -07:00
24 changed files with 384 additions and 104 deletions

View file

@ -1,6 +1,6 @@
name: gradle-ci name: gradle-ci
on: [push, pull_request, workflow_dispatch] on: [ push, pull_request, workflow_dispatch ]
jobs: jobs:
build: build:
@ -8,20 +8,21 @@ jobs:
env: env:
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m" GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m"
SONAR_JDK: "11" SONAR_JDK: "17"
strategy: strategy:
matrix: matrix:
java-version: [ 11, 18 ] java-version: [ 11, 17, 20 ]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK ${{ matrix.java-version }} - name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v1 uses: actions/setup-java@v3
with: with:
distribution: 'zulu'
java-version: ${{ matrix.java-version }} java-version: ${{ matrix.java-version }}
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
@ -29,33 +30,20 @@ jobs:
- name: Cache SonarCloud packages - name: Cache SonarCloud packages
if: matrix.java-version == env.SONAR_JDK if: matrix.java-version == env.SONAR_JDK
uses: actions/cache@v1 uses: actions/cache@v3
with: with:
path: ~/.sonar/cache path: ~/.sonar/cache
key: ${{ runner.os }}-sonar key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar
- name: Cache Gradle packages
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ matrix.java-version }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-${{ matrix.java-version }}-
- name: Test with Gradle - name: Test with Gradle
run: ./gradlew build check --stacktrace uses: gradle/gradle-build-action@v2
with:
arguments: build check --stacktrace
- name: SonarCloud - name: SonarCloud
if: success() && matrix.java-version == env.SONAR_JDK if: success() && matrix.java-version == env.SONAR_JDK
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew sonarqube run: ./gradlew sonar --info
- name: Cleanup Gradle Cache
run: |
rm -f ~/.gradle/caches/modules-2/modules-2.lock
rm -f ~/.gradle/caches/modules-2/gc.properties

1
.gitignore vendored
View file

@ -64,7 +64,6 @@ dist/
ehthumbs.db ehthumbs.db
fabric.properties fabric.properties
gen/ gen/
gradle.properties
hs_err_pid* hs_err_pid*
kobaltBuild kobaltBuild
kobaltw*-test kobaltw*-test

View file

@ -1,4 +1,4 @@
image: gradle:7-jdk11 image: gradle:8-jdk11
variables: variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false" GRADLE_OPTS: "-Dorg.gradle.daemon=false"

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinScriptingSettings">
<option name="suppressDefinitionsCheck" value="true" />
</component>
</project>

2
.idea/kotlinc.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="1.8.0" /> <option name="version" value="1.9.10" />
</component> </component>
</project> </project>

1
.idea/misc.xml generated
View file

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration"> <component name="FrameworkDetectionExcludesConfiguration">

View file

@ -1,8 +1,8 @@
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause) [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](https://opensource.org/licenses/BSD-3-Clause)
[![Kotlin](https://img.shields.io/badge/kotlin-1.8.0-blue)](https://kotlinlang.org/) [![Kotlin](https://img.shields.io/badge/kotlin-1.9.10-7f52ff)](https://kotlinlang.org/)
[![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik/isgd-shorten?label=snapshot&server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/isgd-shorten/) [![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik/isgd-shorten?label=snapshot&server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/isgd-shorten/)
[![release](https://img.shields.io/github/release/ethauvin/isgd-shorten.svg)](https://github.com/ethauvin/isgd-shorten/releases/latest) [![release](https://img.shields.io/github/release/ethauvin/isgd-shorten.svg)](https://github.com/ethauvin/isgd-shorten/releases/latest)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/isgd-shorten/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/isgd-shorten) [![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik/isgd-shorten.svg?color=blue)](https://central.sonatype.com/artifact/net.thauvin.erik/isgd-shorten)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_isgd-shorten&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_isgd-shorten) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_isgd-shorten&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_isgd-shorten)
[![GitHub CI](https://github.com/ethauvin/isgd-shorten/actions/workflows/gradle.yml/badge.svg)](https://github.com/ethauvin/isgd-shorten/actions/workflows/gradle.yml) [![GitHub CI](https://github.com/ethauvin/isgd-shorten/actions/workflows/gradle.yml/badge.svg)](https://github.com/ethauvin/isgd-shorten/actions/workflows/gradle.yml)
@ -46,7 +46,12 @@ returns:
All of the [is.gd API](https://is.gd/developers.php) parameters are supported: All of the [is.gd API](https://is.gd/developers.php) parameters are supported:
```kotlin ```kotlin
Isgd.shorten(url = url, shorturl="foobar", callback = "test", logstats = true, format = Format.JSON) Isgd.shorten(
url = url,
shorturl="foobar",
callback = "test",
logstats = true,
format = Format.JSON)
``` ```
returns: returns:
@ -67,8 +72,31 @@ dependencies {
implementation("net.thauvin.erik:isgd-shorten:0.9.2") implementation("net.thauvin.erik:isgd-shorten:0.9.2")
} }
``` ```
Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/isgd-shorten). Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://central.sonatype.com/artifact/net.thauvin.erik/isgd-shorten).
## Java
To make it easier to use the library with Java, configuration builders are available:
```java
var config = new Config.Builder()
.url("https://www.example.com/")
.shorturl("foobar")
.callback("test")
.logstats(true)
.format(Format.JSON)
.build();
Isgd.shorten(config);
```
```java
var config = new Config.Builder()
.shortUrl("https://is.gd/Pt2sET")
.format(Format.XML)
.build();
Isgd.lookup(config);
```
### Errors ### Errors
An `IsgdException` is thrown when an API error occurs. The error message (text, XML or JSON) and HTTP status code can be retrieved as follows: An `IsgdException` is thrown when an API error occurs. The error message (text, XML or JSON) and HTTP status code can be retrieved as follows:

View file

@ -1,20 +1,20 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("com.github.ben-manes.versions") version "0.44.0" id("com.github.ben-manes.versions") version "0.48.0"
id("io.gitlab.arturbosch.detekt") version "1.22.0" id("io.gitlab.arturbosch.detekt") version "1.23.1"
id("java") id("java")
id("java-library") id("java-library")
id("maven-publish") id("maven-publish")
id("net.thauvin.erik.gradle.semver") version "1.0.4" id("net.thauvin.erik.gradle.semver") version "1.0.4"
id("org.jetbrains.dokka") version "1.7.20" id("org.jetbrains.dokka") version "1.9.0"
id("org.jetbrains.kotlinx.kover") version "0.6.1" id("org.jetbrains.kotlinx.kover") version "0.7.3"
id("org.sonarqube") version "3.5.0.2730" id("org.sonarqube") version "4.3.1.3277"
id("signing") id("signing")
kotlin("jvm") version "1.8.0" kotlin("jvm") version "1.9.10"
kotlin("kapt") version "1.8.0" kotlin("kapt") version "1.9.10"
} }
group = "net.thauvin.erik" group = "net.thauvin.erik"
@ -34,11 +34,11 @@ repositories {
dependencies { dependencies {
implementation(platform(kotlin("bom"))) implementation(platform(kotlin("bom")))
implementation("net.thauvin.erik:urlencoder:1.3.0") implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0")
testImplementation(kotlin("test")) testImplementation(kotlin("test"))
testImplementation(kotlin("test-junit")) testImplementation(kotlin("test-junit"))
testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25") testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.27.0")
} }
java { java {
@ -47,6 +47,17 @@ java {
withSourcesJar() withSourcesJar()
} }
koverReport {
defaults {
xml {
onCheck = true
}
html {
onCheck = true
}
}
}
detekt { detekt {
//toolVersion = "main-SNAPSHOT" //toolVersion = "main-SNAPSHOT"
baseline = project.rootDir.resolve("config/detekt/baseline.xml") baseline = project.rootDir.resolve("config/detekt/baseline.xml")
@ -58,7 +69,7 @@ sonarqube {
property("sonar.organization", "ethauvin-github") property("sonar.organization", "ethauvin-github")
property("sonar.host.url", "https://sonarcloud.io") property("sonar.host.url", "https://sonarcloud.io")
property("sonar.sourceEncoding", "UTF-8") property("sonar.sourceEncoding", "UTF-8")
property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/xml/report.xml") property("sonar.coverage.jacoco.xmlReportPaths", "${layout.buildDirectory.get()}/reports/kover/report.xml")
} }
} }
@ -96,6 +107,15 @@ tasks {
} }
} }
dokkaJavadoc {
dokkaSourceSets {
configureEach {
includes.from("config/dokka/packages.md")
}
}
mustRunAfter("kaptKotlin")
}
val copyToDeploy by registering(Copy::class) { val copyToDeploy by registering(Copy::class) {
from(configurations.runtimeClasspath) { from(configurations.runtimeClasspath) {
exclude("annotations-*.jar") exclude("annotations-*.jar")
@ -122,7 +142,7 @@ tasks {
register("deploy") { register("deploy") {
description = "Copies all needed files to the $deployDir directory." description = "Copies all needed files to the $deployDir directory."
group = PublishingPlugin.PUBLISH_TASK_GROUP group = PublishingPlugin.PUBLISH_TASK_GROUP
dependsOn(clean, wrapper, build, jar) dependsOn(clean, build, jar)
outputs.dir(deployDir) outputs.dir(deployDir)
inputs.files(copyToDeploy) inputs.files(copyToDeploy)
mustRunAfter(clean) mustRunAfter(clean)
@ -131,11 +151,7 @@ tasks {
register("release") { register("release") {
description = "Publishes version ${project.version} to local repository." description = "Publishes version ${project.version} to local repository."
group = PublishingPlugin.PUBLISH_TASK_GROUP group = PublishingPlugin.PUBLISH_TASK_GROUP
dependsOn(wrapper, "deploy", gitTag, publishToMavenLocal) dependsOn("deploy", gitTag, publishToMavenLocal)
}
"sonarqube" {
dependsOn(koverReport)
} }
} }
@ -163,8 +179,8 @@ publishing {
} }
} }
scm { scm {
connection.set("scm:git://github.com/$gitHub.git") connection.set("scm:git:https://github.com/$gitHub.git")
developerConnection.set("scm:git@github.com:$gitHub.git") developerConnection.set("scm:git:git@github.com:$gitHub.git")
url.set(mavenUrl) url.set(mavenUrl)
} }
issueManagement { issueManagement {

View file

@ -5,5 +5,6 @@
<ID>LongParameterList:Isgd.kt$Isgd.Companion$( url: String, shorturl: String = "", callback: String = "", logstats: Boolean = false, format: Format = Format.SIMPLE, isVgd: Boolean = false )</ID> <ID>LongParameterList:Isgd.kt$Isgd.Companion$( url: String, shorturl: String = "", callback: String = "", logstats: Boolean = false, format: Format = Format.SIMPLE, isVgd: Boolean = false )</ID>
<ID>MagicNumber:Isgd.kt$Isgd.Companion$200</ID> <ID>MagicNumber:Isgd.kt$Isgd.Companion$200</ID>
<ID>MagicNumber:Isgd.kt$Isgd.Companion$399</ID> <ID>MagicNumber:Isgd.kt$Isgd.Companion$399</ID>
<ID>WildcardImport:IsgdTest.kt$import assertk.assertions.*</ID>
</CurrentIssues> </CurrentIssues>
</SmellBaseline> </SmellBaseline>

5
config/dokka/packages.md Normal file
View file

@ -0,0 +1,5 @@
# Module isgd-shorten
Isgd Shortener for Kotlin, Java & Android
A simple implementation of the `is.gd` URL shortening and lookup APIs.

View file

@ -2,8 +2,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("application") id("application")
id("com.github.ben-manes.versions") version "0.44.0" id("com.github.ben-manes.versions") version "0.48.0"
kotlin("jvm") version "1.8.0" kotlin("jvm") version "1.9.10"
} }
// ./gradlew run --args='https://www.example.com https://is.gd/Pt2sET' // ./gradlew run --args='https://www.example.com https://is.gd/Pt2sET'

Binary file not shown.

View file

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

30
examples/gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -80,13 +80,10 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -133,22 +130,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in # shell script including quotes and variable substitutions, so put them in
@ -205,6 +213,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

15
examples/gradlew.bat vendored
View file

@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

0
gradle.properties Normal file
View file

Binary file not shown.

View file

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

31
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -80,13 +80,11 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -133,22 +131,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -193,6 +198,10 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in # shell script including quotes and variable substitutions, so put them in
@ -205,6 +214,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

15
gradlew.bat vendored
View file

@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

14
pom.xml
View file

@ -27,8 +27,8 @@
</developer> </developer>
</developers> </developers>
<scm> <scm>
<connection>scm:git://github.com/ethauvin/isgd-shorten.git</connection> <connection>scm:git:https://github.com/ethauvin/isgd-shorten.git</connection>
<developerConnection>scm:git@github.com:ethauvin/isgd-shorten.git</developerConnection> <developerConnection>scm:git:git@github.com:ethauvin/isgd-shorten.git</developerConnection>
<url>https://github.com/ethauvin/isgd-shorten</url> <url>https://github.com/ethauvin/isgd-shorten</url>
</scm> </scm>
<issueManagement> <issueManagement>
@ -40,7 +40,7 @@
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-bom</artifactId> <artifactId>kotlin-bom</artifactId>
<version>1.8.0</version> <version>1.9.10</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
@ -50,13 +50,13 @@
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId> <artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.8.0</version> <version>1.9.10</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.thauvin.erik</groupId> <groupId>net.thauvin.erik.urlencoder</groupId>
<artifactId>urlencoder</artifactId> <artifactId>urlencoder-lib-jvm</artifactId>
<version>1.3.0</version> <version>1.4.0</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -0,0 +1,72 @@
/*
* Config.kt
*
* Copyright 2023 Erik C. Thauvin (erik@thauvin.net)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.isgd
/**
* Provides a builder to create/lookup an is.gd shortlink.
*/
class Config private constructor(
val url: String,
val shorturl: String,
val callback: String,
val logstats: Boolean,
val format: Format,
val isVgd: Boolean
) {
/**
* Configures the parameters to create/lookup an is.gd shortlink.
*/
data class Builder(
var url: String = "",
var shorturl: String = "",
var callback: String = "",
var logstats: Boolean = false,
var format: Format = Format.SIMPLE,
var isVgd: Boolean = false
) {
fun url(url: String) = apply { this.url = url }
fun shorturl(shorturl: String) = apply { this.shorturl = shorturl }
fun callback(callback: String) = apply { this.callback = callback }
fun logstats(logstats: Boolean) = apply { this.logstats = logstats }
fun format(format: Format) = apply { this.format = format }
fun isVgd(isVgd: Boolean) = apply { this.isVgd = isVgd }
fun build() = Config(
url,
shorturl,
callback,
logstats,
format,
isVgd
)
}
}

View file

@ -31,7 +31,7 @@
package net.thauvin.erik.isgd package net.thauvin.erik.isgd
import net.thauvin.erik.urlencoder.UrlEncoder import net.thauvin.erik.urlencoder.UrlEncoderUtil
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
@ -42,7 +42,7 @@ enum class Format(val type: String) {
WEB("web"), SIMPLE("simple"), XML("xml"), JSON("json") WEB("web"), SIMPLE("simple"), XML("xml"), JSON("json")
} }
fun String.encode(): String = UrlEncoder.encode(this) fun String.encode(): String = UrlEncoderUtil.encode(this)
/** /**
* Implements the [is.gd API](https://is.gd/developers.php). * Implements the [is.gd API](https://is.gd/developers.php).
@ -69,6 +69,24 @@ class Isgd private constructor() {
} }
/** /**
* Lookup a shortlink.
*
* See the [is.gd API](https://is.gd/apilookupreference.php).
*/
@JvmStatic
@Throws(IsgdException::class)
fun lookup(config: Config): String {
return lookup(
config.shorturl,
config.callback,
config.format,
config.isVgd
)
}
/**
* Lookup a shortlink.
*
* See the [is.gd API](https://is.gd/apilookupreference.php). * See the [is.gd API](https://is.gd/apilookupreference.php).
*/ */
@JvmStatic @JvmStatic
@ -94,6 +112,26 @@ class Isgd private constructor() {
} }
/** /**
* Shortens a link.
*
* See the [is.gd API](https://is.gd/apishorteningreference.php).
*/
@JvmStatic
@Throws(IsgdException::class)
fun shorten(config: Config): String {
return shorten(
config.url,
config.shorturl,
config.callback,
config.logstats,
config.format,
config.isVgd
)
}
/**
* Shortens a link.
*
* See the [is.gd API](https://is.gd/apishorteningreference.php). * See the [is.gd API](https://is.gd/apishorteningreference.php).
*/ */
@JvmStatic @JvmStatic

View file

@ -33,12 +33,7 @@ package net.thauvin.erik.isgd
import assertk.all import assertk.all
import assertk.assertThat import assertk.assertThat
import assertk.assertions.contains import assertk.assertions.*
import assertk.assertions.isEqualTo
import assertk.assertions.isNotNull
import assertk.assertions.matches
import assertk.assertions.prop
import assertk.assertions.startsWith
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
@ -66,6 +61,15 @@ class IsgdTest {
} }
} }
@Test
fun testExceptionConfig() {
assertFailsWith(
message = "shorten(config:duplicate)",
exceptionClass = IsgdException::class,
block = { Isgd.shorten(Config.Builder().url(shortUrl).build()) }
)
}
@Test @Test
fun testLookup() { fun testLookup() {
assertFailsWith( assertFailsWith(
@ -75,15 +79,35 @@ class IsgdTest {
) )
} }
@Test
fun testLookupConfig() {
assertFailsWith(
message = "lookup(config:empty)",
exceptionClass = IllegalArgumentException::class,
block = { Isgd.lookup(Config.Builder().shorturl("").build()) }
)
}
@Test @Test
fun testLookupDefault() { fun testLookupDefault() {
assertEquals(url, Isgd.lookup(shortUrl)) assertEquals(url, Isgd.lookup(shortUrl))
assertEquals(url, Isgd.lookup(shortVgdUrl, isVgd = true), "lookup(isVgd)") assertEquals(url, Isgd.lookup(shortVgdUrl, isVgd = true), "lookup(isVgd)")
} }
@Test
fun testLookupDefaultConfig() {
assertEquals(url, Isgd.lookup(Config.Builder().shorturl(shortUrl).build()), "lookup(config)")
assertEquals(
url, Isgd.lookup(
Config.Builder().shorturl(shortVgdUrl).isVgd(true).build()
), "lookup(config:isVgd)"
)
}
@Test @Test
fun testLookupJson() { fun testLookupJson() {
assertEquals("{ \"url\": \"$url\" }", Isgd.lookup(shortUrl, format = Format.JSON)) assertEquals("{ \"url\": \"$url\" }", Isgd.lookup(shortUrl, format = Format.JSON))
assertEquals( assertEquals(
"test({ \"url\": \"$url\" });", "test({ \"url\": \"$url\" });",
Isgd.lookup(shortUrl, callback = "test", format = Format.JSON), Isgd.lookup(shortUrl, callback = "test", format = Format.JSON),
@ -91,6 +115,20 @@ class IsgdTest {
) )
} }
@Test
fun testLookupJsonConfig() {
assertEquals(
"{ \"url\": \"$url\" }",
Isgd.lookup(Config.Builder().shorturl(shortUrl).format(Format.JSON).build()), "lookup(config)"
)
assertEquals(
"test({ \"url\": \"$url\" });",
Isgd.lookup(Config.Builder().shorturl(shortUrl).callback("test").format(Format.JSON).build()),
"lookup(config:callback)"
)
}
@Test @Test
fun testLookupXml() { fun testLookupXml() {
assertEquals( assertEquals(
@ -99,6 +137,15 @@ class IsgdTest {
) )
} }
@Test
fun testLookupXmlConfig() {
assertEquals(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><output><url>$url</url></output>",
Isgd.lookup(Config.Builder().shorturl(shortUrl).format(Format.XML).build()),
"lookup(config:xml)"
)
}
@Test @Test
fun testShorten() { fun testShorten() {
assertFailsWith( assertFailsWith(
@ -114,13 +161,38 @@ class IsgdTest {
) )
} }
@Test
fun testShortenConfig() {
assertFailsWith(
message = "shorten(config:empty)",
exceptionClass = IllegalArgumentException::class,
block = { Isgd.shorten(Config.Builder().url("").build()) }
)
assertFailsWith(
message = "shorten(config:shorturl)",
exceptionClass = IsgdException::class,
block = { Isgd.shorten(Config.Builder(url).shorturl("test").build()) }
)
}
@Test @Test
fun testShortenDefault() { fun testShortenDefault() {
assertEquals(shortUrl, Isgd.shorten(url), "shorten(url)") assertEquals(shortUrl, Isgd.shorten(url), "shorten(url)")
assertEquals(shortVgdUrl, Isgd.shorten(url, isVgd = true), "shorten(isVgd)") assertEquals(shortVgdUrl, Isgd.shorten(url, isVgd = true), "shorten(isVgd)")
assertThat(Isgd.shorten(url, logstats = true), "shorten(callback)").matches("https://is.gd/\\w{6}".toRegex()) assertThat(Isgd.shorten(url, logstats = true), "shorten(callback)").matches("https://is.gd/\\w{6}".toRegex())
}
@Test
fun testShortenDefaultConfig() {
assertEquals(shortUrl, Isgd.shorten(Config.Builder().url(url).build()), "shorten(config:url)")
assertEquals(
shortVgdUrl,
Isgd.shorten(Config.Builder().url(url).isVgd(true).build()),
"shorten(config:isVgd)"
)
assertThat(Isgd.shorten(Config.Builder().url(url).logstats(true).build()), "shorten(config:callback)")
.matches("https://is.gd/\\w{6}".toRegex())
} }
@Test @Test
@ -133,6 +205,19 @@ class IsgdTest {
) )
} }
@Test
fun testShortenJsonConfig() {
assertEquals(
"{ \"shorturl\": \"$shortUrl\" }",
Isgd.shorten(Config.Builder().url(url).format(Format.JSON).build()), "shorten(config:json)"
)
assertEquals(
"test({ \"shorturl\": \"$shortUrl\" });",
Isgd.shorten(Config.Builder().url(url).callback("test").format(Format.JSON).build()),
"shorten(config:callback,json)"
)
}
@Test @Test
fun testShortenXml() { fun testShortenXml() {
assertEquals( assertEquals(
@ -142,8 +227,24 @@ class IsgdTest {
) )
} }
@Test
fun testShortenXmlConfig() {
assertEquals(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<output><shorturl>$shortUrl</shorturl></output>",
Isgd.shorten(Config.Builder().url(url).format(Format.XML).build()),
"shorten(config:xml)"
)
}
@Test @Test
fun testShortenWeb() { fun testShortenWeb() {
assertThat(Isgd.shorten(url, format = Format.WEB)).contains(shortUrl) assertThat(Isgd.shorten(url, format = Format.WEB)).contains(shortUrl)
} }
@Test
fun testShortenWebConfig() {
assertThat(Isgd.shorten(Config.Builder().url(url).format(Format.WEB).build()), "shorten(config:web)")
.contains(shortUrl)
}
} }