diff --git a/.circleci/config.yml b/.circleci/config.yml
index d21cbc7..29685bf 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -30,25 +30,25 @@ defaults_gradle: &defaults_gradle
path: build/reports/
jobs:
- build_gradle_jdk14:
+ build_gradle_jdk18:
<<: *defaults
docker:
- - image: openjdk:14-jdk
+ - image: cimg/openjdk:18.0
<<: *defaults_gradle
- build_gradle_jdk8:
+ build_gradle_jdk11:
<<: *defaults
docker:
- - image: circleci/openjdk:8-jdk
+ - image: cimg/openjdk:11.0
<<: *defaults_gradle
workflows:
version: 2
gradle:
- jobs:
- - build_gradle_jdk8
- - build_gradle_jdk14
+ jobs:
+ - build_gradle_jdk11
+ - build_gradle_jdk18
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 540b054..ee7e5da 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -1,21 +1,51 @@
-name: Java CI with Gradle
+name: gradle-ci
-on: [push, pull_request, workflow_dispatch]
+on: [ push, pull_request, workflow_dispatch ]
jobs:
build:
-
runs-on: ubuntu-latest
+ env:
+ GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m"
+ SONAR_JDK: "17"
+
+ strategy:
+ matrix:
+ java-version: [ 11, 17, 20 ]
+
steps:
- - uses: actions/checkout@v2
- - name: Set up JDK 1.8
- uses: actions/setup-java@v1
- with:
- java-version: 1.8
- - name: Grant execute permission for gradlew
- run: chmod +x gradlew
- - name: Test with Gradle
- run: ./gradlew check
- env:
- PINBOARD_API_TOKEN: ${{ secrets.PINBOARD_API_TOKEN }}
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK ${{ matrix.java-version }}
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'zulu'
+ java-version: ${{ matrix.java-version }}
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+
+ - name: Cache SonarCloud packages
+ if: matrix.java-version == env.SONAR_JDK
+ uses: actions/cache@v3
+ with:
+ path: ~/.sonar/cache
+ key: ${{ runner.os }}-sonar
+ restore-keys: ${{ runner.os }}-sonar
+
+ - name: Test with Gradle
+ uses: gradle/gradle-build-action@v2
+ env:
+ PINBOARD_API_TOKEN: ${{ secrets.PINBOARD_API_TOKEN }}
+ with:
+ arguments: build check --stacktrace
+
+ - name: SonarCloud
+ if: success() && matrix.java-version == env.SONAR_JDK
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ run: ./gradlew sonar --info
diff --git a/.gitignore b/.gitignore
index 9dda44b..0742f86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,46 +2,83 @@
!.vscode/launch.json
!.vscode/settings.json
!.vscode/tasks.json
-**/*.class
-**/.idea/**/dataSources.ids
-**/.idea/**/dataSources.local.xml
-**/.idea/**/dataSources/
-**/.idea/**/dbnavigator.xml
-**/.idea/**/dictionaries
-**/.idea/**/dynamic.xml
-**/.idea/**/gradle.xml
-**/.idea/**/libraries
-**/.idea/**/shelf
-**/.idea/**/sqlDataSources.xml
-**/.idea/**/tasks.xml
-**/.idea/**/uiDesigner.xml
-**/.idea/**/usage.statistics.xml
-**/.idea/**/workspace.xml
+*.class
*.code-workspace
+*.ctxt
*.iws
+*.log
+*.nar
+*.rar
*.sublime-*
+*.tar.gz
+*.zip
.DS_Store
.classpath
.gradle
+.history
.kobalt
+.mtj.tmp/
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
.nb-gradle
.project
+.scannerwork
.settings
.vscode/*
-/bin
-/build
-/deploy
-/dist
-/gen
-/gradle.properties
-/local.properties
-/out
-/proguard-project.txt
-/project.properties
-/target
-/test-output
+/**/.idea/$CACHE_FILE$
+/**/.idea/$PRODUCT_WORKSPACE_FILE$
+/**/.idea/**/caches/build_file_checksums.ser
+/**/.idea/**/contentModel.xml
+/**/.idea/**/dataSources.ids
+/**/.idea/**/dataSources.local.xml
+/**/.idea/**/dataSources/
+/**/.idea/**/dbnavigator.xml
+/**/.idea/**/dictionaries
+/**/.idea/**/dynamic.xml
+/**/.idea/**/gradle.xml
+/**/.idea/**/httpRequests
+/**/.idea/**/libraries
+/**/.idea/**/mongoSettings.xml
+/**/.idea/**/replstate.xml
+/**/.idea/**/shelf
+/**/.idea/**/shelf/
+/**/.idea/**/sqlDataSources.xml
+/**/.idea/**/tasks.xml
+/**/.idea/**/uiDesigner.xml
+/**/.idea/**/usage.statistics.xml
+/**/.idea/**/workspace.xml
+/**/.idea/sonarlint*
+/**/.idea_modules/
Thumbs.db
+__pycache__
+atlassian-ide-plugin.xml
+bin/
+build/
+cmake-build-*/
+com_crashlytics_export_strings.xml
+crashlytics-build.properties
+crashlytics.properties
+dependency-reduced-pom.xml
+deploy/
+dist/
ehthumbs.db
+fabric.properties
+gen/
+hs_err_pid*
kobaltBuild
kobaltw*-test
+lib/kotlin*
+libs/
+local.properties
+out/
pom.xml.asc
+pom.xml.next
+pom.xml.releaseBackup
+pom.xml.tag
+pom.xml.versionsBackup
+proguard-project.txt
+project.properties
+release.properties
+target/
+test-output
+venv
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 26820aa..1a3e8b4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: gradle:alpine
+image: gradle:8-jdk11
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
@@ -12,7 +12,7 @@ stages:
build:
stage: build
- script: ./gradlew --build-cache assemble
+ script: gradle --build-cache assemble
cache:
key: "$CI_COMMIT_REF_NAME"
policy: push
@@ -22,7 +22,7 @@ build:
test:
stage: test
- script: ./gradlew check
+ script: gradle check
cache:
key: "$CI_COMMIT_REF_NAME"
policy: pull
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..10aa334
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,298 @@
+
+
+
+
+
+
+
+
+
+
+ OVERRIDDEN_METHODS
+ BY_NAME
+
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+ true
+
+ BY_NAME
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+ BY_NAME
+
+
+
+
+
+ true
+
+ BY_NAME
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
index d91f848..6e6eec1 100644
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -1,5 +1,6 @@
-
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 4e8da37..88fa664 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -4,18 +4,9 @@
-
-
-
-
-
-
-
-
-
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 8ff795e..562d6ca 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,8 +1,6 @@
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..dd4c951
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 3d4ac96..646928b 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -21,5 +21,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml
deleted file mode 100644
index bc444de..0000000
--- a/.idea/kotlinScripting.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 5a05248..44174d6 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -5,7 +5,10 @@
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries-with-intellij-classes.xml b/.idea/libraries-with-intellij-classes.xml
new file mode 100644
index 0000000..9fa3156
--- /dev/null
+++ b/.idea/libraries-with-intellij-classes.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 794aa67..4ca97d5 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,7 @@
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 0cc12b3..917a540 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,15 +2,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/.idea/modules/kotlin.samples-kotlin.iml b/.idea/modules/kotlin.samples-kotlin.iml
deleted file mode 100644
index 16c524b..0000000
--- a/.idea/modules/kotlin.samples-kotlin.iml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/kotlin.samples-kotlin.main.iml b/.idea/modules/kotlin.samples-kotlin.main.iml
deleted file mode 100644
index fbd1150..0000000
--- a/.idea/modules/kotlin.samples-kotlin.main.iml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/kotlin.samples-kotlin.test.iml b/.idea/modules/kotlin.samples-kotlin.test.iml
deleted file mode 100644
index 2b9c8df..0000000
--- a/.idea/modules/kotlin.samples-kotlin.test.iml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/pinboard-poster.main.iml b/.idea/modules/pinboard-poster.main.iml
deleted file mode 100644
index d1e6600..0000000
--- a/.idea/modules/pinboard-poster.main.iml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/pinboard-poster.test.iml b/.idea/modules/pinboard-poster.test.iml
deleted file mode 100644
index 72b3d91..0000000
--- a/.idea/modules/pinboard-poster.test.iml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/samples-java.iml b/.idea/modules/samples-java.iml
deleted file mode 100644
index 19b4065..0000000
--- a/.idea/modules/samples-java.iml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/samples-java.main.iml b/.idea/modules/samples-java.main.iml
deleted file mode 100644
index 9a2896e..0000000
--- a/.idea/modules/samples-java.main.iml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules/samples-java.test.iml b/.idea/modules/samples-java.test.iml
deleted file mode 100644
index 100a3c5..0000000
--- a/.idea/modules/samples-java.test.iml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 48c5805..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-language: java
-dist: trusty
-
-env:
- global:
- - CI=true
-
-#install:
-# - git fetch --unshallow --tags
-
-addons:
- sonarcloud:
- organization: "ethauvin-github"
-
-jdk:
- - oraclejdk8
- - openjdk14
-
-before_install:
- - chmod +x gradlew
-
-after_success:
- - |
- if [ "${TRAVIS_TEST_RESULT}" == 0 ] && [ "$TRAVIS_JDK_VERSION" == "openjdk14" ]; then
- ./gradlew sonarqube
- fi
diff --git a/LICENSE.txt b/LICENSE.txt
index 8e33202..d53e5a1 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2017-2021, Erik C. Thauvin (erik@thauvin.net)
+Copyright (c) 2017-2023, Erik C. Thauvin (erik@thauvin.net)
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index 1d2bd5a..0e3754e 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,13 @@
-# [Pinboard](https://pinboard.in) Poster for Kotlin/Java
+# [Pinboard](https://pinboard.in) Poster for Kotlin, Java and Android
-[](http://opensource.org/licenses/BSD-3-Clause) [](https://github.com/ethauvin/pinboard-poster/releases/latest) [](https://search.maven.org/search?q=g:%22net.thauvin.erik%22%20AND%20a:%22pinboard-poster%22)
+[](https://opensource.org/licenses/BSD-3-Clause) [](https://github.com/ethauvin/pinboard-poster/releases/latest)
+[](https://central.sonatype.com/artifact/net.thauvin.erik/pinboard-poster)
-[](https://snyk.io/test/github/ethauvin/pinboard-poster?targetFile=pom.xml) [](https://sonarcloud.io/dashboard?id=ethauvin_pinboard-poster) [](https://travis-ci.com/ethauvin/pinboard-poster) [](https://circleci.com/gh/ethauvin/pinboard-poster/tree/master)
+[](https://sonarcloud.io/dashboard?id=ethauvin_pinboard-poster)
+[](https://github.com/ethauvin/pinboard-poster/actions/workflows/gradle.yml)
+[](https://circleci.com/gh/ethauvin/pinboard-poster/tree/master)
-A small Kotlin/Java/Android library for posting to [Pinboard](https://pinboard.in).
+A small library for posting to [Pinboard](https://pinboard.in).
## Examples
@@ -14,20 +17,29 @@ A small Kotlin/Java/Android library for posting to [Pinboard](https://pinboard.i
val poster = PinboardPoster("user:TOKEN")
-poster.addPin("http://www.example.com/foo", "This is a test")
-poster.deletePin("http:///www.example.com/bar")
+poster.addPin("https://www.example.com/foo", "This is a test")
+poster.addPin("https://examples.com", "This is a test", tags = arrayOf("foo", "bar"))
+poster.deletePin("https:///www.example.com/bar")
```
+
[View Example](https://github.com/ethauvin/pinboard-poster/blob/master/samples/kotlin/src/main/kotlin/net/thauvin/erik/pinboard/samples/KotlinExample.kt)
### Java
+
```java
final PinboardPoster poster = new PinBboardPoster("user:TOKEN");
-poster.addPin("http://www.example.com/foo", "This is a test");
-poster.deletePin("http:///www.example.com/bar");
+poster.addPin("https://www.example.com/foo", "This is a test");
+poster.addPin(new PinConfig.Builder()
+ .url("https://example.com")
+ .description("This is a test")
+ .tags("foo", "bar")
+ .build());
+poster.deletePin("https:///www.example.com/bar");
```
+
[View Example](https://github.com/ethauvin/pinboard-poster/blob/master/samples/java/src/main/java/net/thauvin/erik/pinboard/samples/JavaExample.java)
Your API authentication token is available on the [Pinboard settings page](https://pinboard.in/settings/password).
@@ -37,28 +49,37 @@ Your API authentication token is available on the [Pinboard settings page](https
To install and run from Gradle, add the following to the build.gradle file:
```gradle
+repositories {
+ mavenCentral()
+}
+
dependencies {
- compile 'net.thauvin.erik:pinboard-poster:1.0.3'
+ compile 'net.thauvin.erik:pinboard-poster:1.0.4'
}
```
+
[View Example](https://github.com/ethauvin/pinboard-poster/blob/master/samples/java/build.gradle)
[View Kotlin DSL Example](https://github.com/ethauvin/pinboard-poster/blob/master/samples/kotlin/build.gradle.kts)
-Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://search.maven.org/artifact/net.thauvin.erik/pinboard-poster/1.0.3/jar).
+Instructions for using with Maven, Ivy, etc. can be found on [Maven Central](https://central.sonatype.com/artifact/net.thauvin.erik/pinboard-poster).
## Adding
The `addPin` function support all of the [Pinboard API parameters](https://pinboard.in/api/#posts_add):
```kotlin
-poster.addPin(url = "http://www.example.com",
- description = "This is the title",
- extended = "This is the extended description.",
- tags = "tag1 tag2 tag3",
- dt = "2010-12-11T19:48:02Z",
- replace = true,
- shared = true,
- toRead = false)
+import java.time.ZonedDateTime
+
+poster.addPin(
+ url = "https://www.example.com",
+ description = "This is the title",
+ extended = "This is the extended description.",
+ tags = arrayOf("tag1", "tag2", "tag3"),
+ dt = ZonedDateTime.now(),
+ replace = true,
+ shared = true,
+ toRead = false
+)
```
`url` and `description` are required.
@@ -70,7 +91,7 @@ It returns `true` if the bookmark was added successfully, `false` otherwise.
The `deletePin` function support all of the [Pinboard API parameters](https://pinboard.in/api/#posts_delete):
```kotlin
-poster.deletePin(url = "http://www.example.com/")
+poster.deletePin(url = "https://www.example.com/")
```
It returns `true` if the bookmark was deleted successfully, `false` otherwise.
@@ -80,13 +101,16 @@ It returns `true` if the bookmark was deleted successfully, `false` otherwise.
The library used [`java.util.logging`](https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html) to log errors. Logging can be configured as follows:
#### Kotlin
+
```kotlin
with(poster.logger) {
addHandler(ConsoleHandler().apply { level = Level.FINE })
level = Level.FINE
}
```
+
#### Java
+
```java
final ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.FINE);
diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml
index 7d98402..a9514a0 100644
--- a/bitbucket-pipelines.yml
+++ b/bitbucket-pipelines.yml
@@ -1,4 +1,4 @@
-image: openjdk:8
+image: maven:3-openjdk-18
pipelines:
default:
diff --git a/build.gradle.kts b/build.gradle.kts
index 01b2d22..b7cc892 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,20 +1,23 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
plugins {
- jacoco
- java
- kotlin("jvm") version "1.4.31"
- `maven-publish`
- signing
- id("com.github.ben-manes.versions") version "0.38.0"
- id("io.gitlab.arturbosch.detekt") version "1.16.0"
- id("org.jetbrains.dokka") version "1.4.30"
- id("org.sonarqube") version "3.1.1"
+ id("com.github.ben-manes.versions") version "0.48.0"
+ id("io.gitlab.arturbosch.detekt") version "1.23.1"
+ id("java")
+ id("maven-publish")
+ id("org.jetbrains.dokka") version "1.9.0"
+ id("org.jetbrains.kotlinx.kover") version "0.7.3"
+ id("org.sonarqube") version "4.4.0.3356"
+ id("signing")
+ kotlin("jvm") version "1.9.10"
}
group = "net.thauvin.erik"
-version = "1.0.3"
-description = "Pinboard Poster for Kotlin/Java"
+version = "1.0.4-SNAPSHOT"
+description = "A small library for posting to Pinboard"
val gitHub = "ethauvin/$name"
val mavenUrl = "https://github.com/$gitHub"
@@ -23,38 +26,61 @@ var isRelease = "release" in gradle.startParameter.taskNames
val publicationName = "mavenJava"
-object VersionInfo {
- const val okhttp = "4.9.1"
+object Versions {
+ const val OKHTTP = "4.11.0"
}
-val versions: VersionInfo by extra { VersionInfo }
+fun isNonStable(version: String): Boolean {
+ val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.uppercase().contains(it) }
+ val regex = "^[0-9,.v-]+(-r)?$".toRegex()
+ val isStable = stableKeyword || regex.matches(version)
+ return isStable.not()
+}
repositories {
mavenCentral()
- jcenter() // needed for Dokka
+ maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") }
}
dependencies {
- implementation("com.squareup.okhttp3:okhttp:${versions.okhttp}")
- implementation("com.squareup.okhttp3:logging-interceptor:${versions.okhttp}")
+ implementation(platform(kotlin("bom")))
- testImplementation("org.testng:testng:7.4.0")
+ implementation("com.squareup.okhttp3:okhttp:${Versions.OKHTTP}")
+ implementation("com.squareup.okio:okio:3.5.0")
+ implementation("com.squareup.okhttp3:logging-interceptor:${Versions.OKHTTP}")
+
+ testImplementation("org.testng:testng:7.8.0")
}
java {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
withSourcesJar()
}
detekt {
+ //toolVersion = "main-SNAPSHOT"
baseline = project.rootDir.resolve("config/detekt/baseline.xml")
}
+koverReport {
+ defaults {
+ xml {
+ onCheck = true
+ }
+ html {
+ onCheck = true
+ }
+ }
+}
+
sonarqube {
properties {
- property("sonar.projectKey", "ethauvin_pinboard-poster")
+ property("sonar.projectKey", "ethauvin_$name")
+ property("sonar.organization", "ethauvin-github")
+ property("sonar.host.url", "https://sonarcloud.io")
property("sonar.sourceEncoding", "UTF-8")
+ property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/report.xml")
}
}
@@ -68,26 +94,26 @@ val javadocJar by tasks.creating(Jar::class) {
tasks {
withType {
+ testLogging {
+ exceptionFormat = TestExceptionFormat.FULL
+ events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
+ }
+
useTestNG()
}
- withType {
- reports {
- xml.isEnabled = true
- html.isEnabled = true
- }
- }
-
withType {
- kotlinOptions.jvmTarget = "1.8"
+ kotlinOptions.jvmTarget = java.targetCompatibility.toString()
}
withType {
destination = file("$projectDir/pom.xml")
}
- assemble {
- dependsOn(javadocJar)
+ withType {
+ rejectVersionIf {
+ isNonStable(candidate.version)
+ }
}
clean {
@@ -97,8 +123,9 @@ tasks {
}
val copyToDeploy by registering(Copy::class) {
- from(configurations.runtime) {
+ from(configurations.runtimeClasspath) {
exclude("annotations-*.jar")
+ exclude("kotlin-*.jar")
}
from(jar)
into(deployDir)
@@ -107,10 +134,10 @@ tasks {
register("deploy") {
description = "Copies all needed files to the $deployDir directory."
group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn("build", "jar")
+ dependsOn(clean, build, jar)
outputs.dir(deployDir)
inputs.files(copyToDeploy)
- mustRunAfter("clean")
+ mustRunAfter(clean)
}
val gitIsDirty by registering(Exec::class) {
@@ -128,19 +155,10 @@ tasks {
}
}
- buildScan {
- termsOfServiceUrl = "https://gradle.com/terms-of-service"
- setTermsOfServiceAgree("yes")
- }
-
register("release") {
description = "Publishes version ${project.version} to local repository."
group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn("wrapper", "deploy", "gitTag", "publishToMavenLocal")
- }
-
- "sonarqube" {
- dependsOn("jacocoTestReport")
+ dependsOn(wrapper, "deploy", gitTag, publishToMavenLocal)
}
}
@@ -168,9 +186,9 @@ publishing {
}
}
scm {
- connection.set("scm:git:git://github.com/$gitHub.git")
+ connection.set("scm:git:https//github.com/$gitHub.git")
developerConnection.set("scm:git:git@github.com:$gitHub.git")
- url.set("$mavenUrl")
+ url.set(mavenUrl)
}
issueManagement {
system.set("GitHub")
@@ -182,7 +200,9 @@ publishing {
repositories {
maven {
name = "ossrh"
- url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
+ url = if (project.version.toString().contains("SNAPSHOT"))
+ uri("https://oss.sonatype.org/content/repositories/snapshots/") else
+ uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials(PasswordCredentials::class)
}
}
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index 23161d0..278860b 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -1,11 +1,12 @@
-
+
-
-
- ComplexMethod:PinboardPoster.kt$PinboardPoster$private fun executeMethod(method: String, params: List<Pair<String, String>>): Boolean
- LongParameterList:PinboardPoster.kt$PinboardPoster$( url: String, description: String, extended: String = "", tags: String = "", dt: String = "", replace: Boolean = true, shared: Boolean = true, toRead: Boolean = false )
- NestedBlockDepth:PinboardPoster.kt$PinboardPoster$private fun executeMethod(method: String, params: List<Pair<String, String>>): Boolean
- ThrowsCount:PinboardPoster.kt$PinboardPoster$internal fun parseMethodResponse(method: String, response: String)
- TooGenericExceptionCaught:PinboardPoster.kt$PinboardPoster$e: Exception
-
-
\ No newline at end of file
+
+
+ LongParameterList:PinConfig.kt$PinConfig$( val url: String, val description: String, val extended: String, val tags: Array<out String>, val dt: ZonedDateTime, val replace: Boolean, val shared: Boolean, val toRead: Boolean )
+ LongParameterList:PinboardPoster.kt$PinboardPoster$( url: String, description: String, extended: String = "", vararg tags: String = emptyArray(), dt: ZonedDateTime = ZonedDateTime.now(), replace: Boolean = true, shared: Boolean = true, toRead: Boolean = false )
+ NestedBlockDepth:PinboardPoster.kt$PinboardPoster$private fun executeMethod(method: String, params: Map<String, String>): Boolean
+ ThrowsCount:PinboardPoster.kt$PinboardPoster$@Throws(IOException::class) internal fun parseMethodResponse(method: String, response: String)
+ TooManyFunctions:PinConfig.kt$PinConfig$Builder
+ WildcardImport:PinboardPosterTest.kt$import org.testng.Assert.*
+
+
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..f7caf5f
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+./gradlew deploy
+[ $? -eq 0 ] && scp deploy/*.jar nix3.thauvin.us:/opt/lib/jtalk-ee/pinboard-poster
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..e69de29
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e708b1c..7f93135 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 442d913..ac72c34 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 4f906e0..0adc8e1 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,99 @@
#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# 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"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- 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.
+ JAVACMD=java
+ 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
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ 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 ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | 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" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+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;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ 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.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 107acd3..93e3f59 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
echo.
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
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/pinboard-poster.iml b/pinboard-poster.iml
index 82e18fd..6afc535 100644
--- a/pinboard-poster.iml
+++ b/pinboard-poster.iml
@@ -1,10 +1,11 @@
-
+
+
@@ -17,15 +18,4 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 18b708b..aa3e2f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,5 @@
-
+
@@ -8,9 +8,9 @@
4.0.0
net.thauvin.erik
pinboard-poster
- 1.0.3
+ 1.0.4-SNAPSHOT
pinboard-poster
- Pinboard Poster for Kotlin/Java
+ A small library for posting to Pinboard
https://github.com/ethauvin/pinboard-poster
@@ -27,7 +27,7 @@
- scm:git:git://github.com/ethauvin/pinboard-poster.git
+ scm:git:https//github.com/ethauvin/pinboard-poster.git
scm:git:git@github.com:ethauvin/pinboard-poster.git
https://github.com/ethauvin/pinboard-poster
@@ -35,23 +35,40 @@
GitHub
https://github.com/ethauvin/pinboard-poster/issues
+
+
+
+ org.jetbrains.kotlin
+ kotlin-bom
+ 1.9.10
+ pom
+ import
+
+
+
org.jetbrains.kotlin
kotlin-stdlib-jdk8
- 1.4.31
+ 1.9.10
compile
com.squareup.okhttp3
okhttp
- 4.9.1
+ 4.11.0
+ runtime
+
+
+ com.squareup.okio
+ okio-jvm
+ 3.5.0
runtime
com.squareup.okhttp3
logging-interceptor
- 4.9.1
+ 4.11.0
runtime
diff --git a/preflightcheck.sh b/preflightcheck.sh
old mode 100644
new mode 100755
index ed82ca7..fcfafb8
--- a/preflightcheck.sh
+++ b/preflightcheck.sh
@@ -2,7 +2,7 @@
# set source and test locations
src="src/main/kotlin/net/thauvin/erik/pinboard"
-test="src/main/kotlin/net/thauvin/erik/pinboard"
+test="src/test/kotlin/net/thauvin/erik/pinboard"
# e.g: .java, .kt, etc.
ext=".kt"
java8=true
@@ -11,16 +11,16 @@ declare -a examples=(
"samples/java run"
"samples/kotlin run")
# e.g: empty or javadoc, etc.
-gradle_doc="dokka"
+gradle_doc="dokkaJavadoc"
# e.g. empty or sonarqube
-gradle_sonar="sonarqube"
+gradle_sonar="sonar"
# gradle options for examples
gradle_opts="--console=plain --no-build-cache --no-daemon"
# maven arguments for examples
maven_args=""
#
-# Version: 1.1.4
+# Version: 1.1.5
#
if [ "$java8" = true ]
@@ -40,7 +40,7 @@ pause() {
}
checkCopyright() {
- if [ "$(grep -c "$date" "$1")" -eq 0 ]
+ if [ "$(grep -c "$date" "$1")" == "0" ]
then
echo -e " Invalid: ${red}$f${std}"
else
@@ -59,20 +59,6 @@ runGradle() {
cd "$pwd"
}
-runKobalt() {
- cd "$1" || exit 1
- if [ -f kobalt/src/Build.kt ]
- then
- clear
- reset
- echo -e "> Project: ${cyan}${1}${std} [Kobalt]"
- shift
- ./kobaltw $@ || exit 1
- pause
- fi
- cd "$pwd"
-}
-
runMaven() {
cd "$1" || exit 1
if [ -f pom.xml ]
@@ -104,7 +90,6 @@ checkDeps() {
* ) for ex in "${!examples[@]}"
do
runGradle $(echo "${examples[ex]}" | cut -d " " -f 1) dU
- # runKobalt $(echo "${examples[ex]}" | cut -d " " -f 1) checkVersions
runMaven $(echo "${examples[ex]}" | cut -d " " -f 1) versions:display-dependency-updates
if [ "$ex" -eq "${#examples}" ]
then
@@ -130,7 +115,6 @@ runExamples() {
for ex in "${!examples[@]}"
do
runGradle ${examples[ex]} clean $gradle_opts
- # runKobalt ${examples[ex]} clean
runMaven $(echo "${examples[ex]}" | cut -d " " -f 1) clean $maven_args
done
}
@@ -152,7 +136,6 @@ examplesMenu() {
examplesMenu
else
runGradle ${examples[$(($choice - 1))]}
- # runKobalt ${examples[$(($choice - 1))]}
runMaven $(echo "${examples[$(($choice - 1))]}" | cut -d " " -f 1) $maven_args
examplesMenu
fi ;;
@@ -163,7 +146,7 @@ examplesMenu() {
validateCopyrights() {
clear
echo -e "${cyan}Validating copyrights...${std}"
- for f in "LICENSE.TXT" ${src}/*${ext} ${test}/*${ext}
+ for f in "LICENSE.txt" ${src}/*${ext} ${test}/*${ext}
do
if [ -f "$f" ]
then
diff --git a/samples/java/build.gradle b/samples/java/build.gradle
index 01c54f4..49d46b8 100644
--- a/samples/java/build.gradle
+++ b/samples/java/build.gradle
@@ -1,4 +1,5 @@
plugins {
+ id 'com.github.ben-manes.versions' version '0.48.0'
id 'java'
id 'application'
}
@@ -9,11 +10,16 @@ defaultTasks 'run'
mainClassName = 'net.thauvin.erik.pinboard.samples.JavaExample'
+java {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+}
+
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
- compile 'net.thauvin.erik:pinboard-poster:1.0.3'
+ implementation 'net.thauvin.erik:pinboard-poster:1.0.4-SNAPSHOT'
}
diff --git a/samples/java/gradle/wrapper/gradle-wrapper.jar b/samples/java/gradle/wrapper/gradle-wrapper.jar
index e708b1c..7f93135 100644
Binary files a/samples/java/gradle/wrapper/gradle-wrapper.jar and b/samples/java/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/java/gradle/wrapper/gradle-wrapper.properties b/samples/java/gradle/wrapper/gradle-wrapper.properties
index 442d913..ac72c34 100644
--- a/samples/java/gradle/wrapper/gradle-wrapper.properties
+++ b/samples/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/samples/java/gradlew b/samples/java/gradlew
index 4f906e0..0adc8e1 100755
--- a/samples/java/gradlew
+++ b/samples/java/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,99 @@
#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# 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"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- 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.
+ JAVACMD=java
+ 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
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ 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 ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | 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" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+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;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ 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.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/samples/java/gradlew.bat b/samples/java/gradlew.bat
index 107acd3..93e3f59 100644
--- a/samples/java/gradlew.bat
+++ b/samples/java/gradlew.bat
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
echo.
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
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/samples/java/src/main/java/net/thauvin/erik/pinboard/samples/JavaExample.java b/samples/java/src/main/java/net/thauvin/erik/pinboard/samples/JavaExample.java
index e6da4fc..0aa16f0 100644
--- a/samples/java/src/main/java/net/thauvin/erik/pinboard/samples/JavaExample.java
+++ b/samples/java/src/main/java/net/thauvin/erik/pinboard/samples/JavaExample.java
@@ -1,36 +1,6 @@
-/*
- * JavaExample.java
- *
- * Copyright (c) 2017-2018, Erik C. Thauvin (erik@thauvin.net)
- * All rights reserved.
- *
- * 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.pinboard.samples;
+import net.thauvin.erik.pinboard.PinConfig;
import net.thauvin.erik.pinboard.PinboardPoster;
import java.nio.file.Paths;
@@ -40,7 +10,7 @@ import java.util.logging.Logger;
public class JavaExample {
public static void main(String[] args) {
- final String url = "http://www.example.com/pinboard";
+ final String url = "https://example.com/pinboard";
final PinboardPoster poster;
if (args.length == 1) {
@@ -59,7 +29,12 @@ public class JavaExample {
logger.setLevel(Level.FINE);
// Add Pin
- if (poster.addPin(url, "Testing", "Extended test", "test java")) {
+ if (poster.addPin(new PinConfig.Builder()
+ .url(url)
+ .description("Testing")
+ .extended("Extra")
+ .tags("test", "java")
+ .build())) {
System.out.println("Added: " + url);
}
diff --git a/samples/kotlin/build.gradle.kts b/samples/kotlin/build.gradle.kts
index 5fa0d8e..a42f78d 100644
--- a/samples/kotlin/build.gradle.kts
+++ b/samples/kotlin/build.gradle.kts
@@ -1,6 +1,9 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
plugins {
- application
- kotlin("jvm") version "1.4.31"
+ id("application")
+ id("com.github.ben-manes.versions") version "0.48.0"
+ kotlin("jvm") version "1.9.10"
}
// ./gradlew run
@@ -13,9 +16,20 @@ repositories {
}
dependencies {
- compile("net.thauvin.erik:pinboard-poster:1.0.3")
+ implementation("net.thauvin.erik:pinboard-poster:1.0.4-SNAPSHOT")
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
}
application {
- mainClassName = "net.thauvin.erik.pinboard.samples.KotlinExampleKt"
+ mainClass.set("net.thauvin.erik.pinboard.samples.KotlinExampleKt")
+}
+
+tasks {
+ withType().configureEach {
+ kotlinOptions.jvmTarget = java.targetCompatibility.toString()
+ }
}
diff --git a/samples/kotlin/gradle/wrapper/gradle-wrapper.jar b/samples/kotlin/gradle/wrapper/gradle-wrapper.jar
index e708b1c..7f93135 100644
Binary files a/samples/kotlin/gradle/wrapper/gradle-wrapper.jar and b/samples/kotlin/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/samples/kotlin/gradle/wrapper/gradle-wrapper.properties b/samples/kotlin/gradle/wrapper/gradle-wrapper.properties
index 442d913..ac72c34 100644
--- a/samples/kotlin/gradle/wrapper/gradle-wrapper.properties
+++ b/samples/kotlin/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/samples/kotlin/gradlew b/samples/kotlin/gradlew
index 4f906e0..0adc8e1 100755
--- a/samples/kotlin/gradlew
+++ b/samples/kotlin/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,99 @@
#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# 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"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- 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.
+ JAVACMD=java
+ 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
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ 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 ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | 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" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+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;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ 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.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/samples/kotlin/gradlew.bat b/samples/kotlin/gradlew.bat
index 107acd3..93e3f59 100644
--- a/samples/kotlin/gradlew.bat
+++ b/samples/kotlin/gradlew.bat
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
echo.
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
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/samples/kotlin/src/main/kotlin/net/thauvin/erik/pinboard/samples/KotlinExample.kt b/samples/kotlin/src/main/kotlin/net/thauvin/erik/pinboard/samples/KotlinExample.kt
index 77c8ba5..0582144 100644
--- a/samples/kotlin/src/main/kotlin/net/thauvin/erik/pinboard/samples/KotlinExample.kt
+++ b/samples/kotlin/src/main/kotlin/net/thauvin/erik/pinboard/samples/KotlinExample.kt
@@ -1,34 +1,3 @@
-/*
- * KotlinExample.kt
- *
- * Copyright (c) 2017-2018, Erik C. Thauvin (erik@thauvin.net)
- * All rights reserved.
- *
- * 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.pinboard.samples
import net.thauvin.erik.pinboard.PinboardPoster
@@ -37,7 +6,7 @@ import java.util.logging.ConsoleHandler
import java.util.logging.Level
fun main(args: Array) {
- val url = "http://www.example.com/pinboard"
+ val url = "https://example.com/pinboard"
val poster = if (args.size == 1) {
// API Token is an argument
@@ -54,7 +23,7 @@ fun main(args: Array) {
}
// Add Pin
- if (poster.addPin(url, "Testing", "Extended test", "test kotlin")) {
+ if (poster.addPin(url, "Testing", "Extended test", tags = arrayOf("test", "kotlin"))) {
println("Added: $url")
}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 754ad3d..c0e5354 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,11 +1,19 @@
plugins {
- id("com.gradle.enterprise").version("3.1.1")
+ id("com.gradle.enterprise").version("3.6.3")
+}
+
+gradleEnterprise {
+ buildScan {
+ link("GitHub", "https://github.com/ethauvin/pinboard-poster/tree/master")
+ if (!System.getenv("CI").isNullOrEmpty()) {
+ isUploadInBackground = false
+ publishOnFailure()
+ tag("CI")
+ }
+ termsOfServiceUrl = "https://gradle.com/terms-of-service"
+ termsOfServiceAgree = "yes"
+ }
}
rootProject.name = "pinboard-poster"
-gradleEnterprise {
- buildScan {
- // plugin configuration
- }
-}
diff --git a/src/main/kotlin/net/thauvin/erik/pinboard/PinConfig.kt b/src/main/kotlin/net/thauvin/erik/pinboard/PinConfig.kt
new file mode 100644
index 0000000..f0d6cea
--- /dev/null
+++ b/src/main/kotlin/net/thauvin/erik/pinboard/PinConfig.kt
@@ -0,0 +1,119 @@
+/*
+ * PinConfig.kt
+ *
+ * Copyright (c) 2017-2023, Erik C. Thauvin (erik@thauvin.net)
+ * All rights reserved.
+ *
+ * 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.pinboard
+
+import java.time.ZonedDateTime
+
+/**
+ * Provides a builder to add a pin.
+ */
+class PinConfig private constructor(
+ val url: String,
+ val description: String,
+ val extended: String,
+ val tags: Array,
+ val dt: ZonedDateTime,
+ val replace: Boolean,
+ val shared: Boolean,
+ val toRead: Boolean
+) {
+ /**
+ * Configures the parameters to add a pin.
+ */
+ data class Builder(
+ private var url: String = "",
+ private var description: String = "",
+ private var extended: String = "",
+ private var tags: Array = emptyArray(),
+ private var dt: ZonedDateTime = ZonedDateTime.now(),
+ private var replace: Boolean = true,
+ private var shared: Boolean = true,
+ private var toRead: Boolean = false
+ ) {
+ fun url(url: String) = apply { this.url = url }
+ fun description(description: String) = apply { this.description = description }
+ fun extended(extended: String) = apply { this.extended = extended }
+ fun tags(vararg tag: String) = apply { this.tags = tag }
+ fun dt(datetime: ZonedDateTime) = apply { this.dt = datetime }
+ fun replace(replace: Boolean) = apply { this.replace = replace }
+ fun shared(shared: Boolean) = apply { this.shared = shared }
+ fun toRead(toRead: Boolean) = apply { this.toRead = toRead }
+
+ fun build() = PinConfig(
+ url,
+ description,
+ extended,
+ tags,
+ dt,
+ replace,
+ shared,
+ toRead
+ )
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Builder
+
+ if (url != other.url) return false
+ if (description != other.description) return false
+ if (extended != other.extended) return false
+ if (!tags.contentEquals(other.tags)) return false
+ if (dt != other.dt) return false
+ if (replace != other.replace) return false
+ if (shared != other.shared) return false
+ if (toRead != other.toRead) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = url.hashCode()
+ result = 31 * result + description.hashCode()
+ result = 31 * result + extended.hashCode()
+ result = 31 * result + tags.contentHashCode()
+ result = 31 * result + dt.hashCode()
+ result = 31 * result + replace.hashCode()
+ result = 31 * result + shared.hashCode()
+ result = 31 * result + toRead.hashCode()
+ return result
+ }
+
+ override fun toString(): String {
+ return "Builder(url='$url', description='$description', extended='$extended'," +
+ "tags=${tags.contentToString()}, dt=$dt, replace=$replace, shared=$shared, toRead=$toRead)"
+ }
+
+
+ }
+}
diff --git a/src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt b/src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt
index ef2a864..0b9514d 100644
--- a/src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt
+++ b/src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt
@@ -1,7 +1,7 @@
/*
* PinboardPoster.kt
*
- * Copyright (c) 2017-2021, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2017-2023, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,8 @@ import java.net.MalformedURLException
import java.net.URL
import java.nio.file.Files
import java.nio.file.Path
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
import java.util.*
import java.util.logging.Level
import java.util.logging.Logger
@@ -81,7 +83,6 @@ open class PinboardPoster() {
* @param properties The properties.
* @param key The property key.
*/
- @Suppress("unused")
@JvmOverloads
constructor(properties: Properties, key: String = Constants.ENV_API_TOKEN) : this() {
apiToken = properties.getProperty(key, apiToken)
@@ -121,7 +122,6 @@ open class PinboardPoster() {
var apiEndPoint: String = Constants.API_ENDPOINT
/** The logger instance. **/
- @Suppress("MemberVisibilityCanBePrivate")
val logger: Logger by lazy { Logger.getLogger(PinboardPoster::class.java.simpleName) }
private val client by lazy {
@@ -134,6 +134,24 @@ open class PinboardPoster() {
}.build()
}
+ /**
+ * Adds a bookmark to Pinboard
+ *
+ * This method supports of all the [Pinboard API Parameters](https://pinboard.in/api/#posts_add).
+ */
+ fun addPin(config: PinConfig): Boolean {
+ return addPin(
+ url = config.url,
+ description = config.description,
+ extended = config.extended,
+ tags = config.tags,
+ dt = config.dt,
+ replace = config.replace,
+ shared = config.shared,
+ toRead = config.toRead
+ )
+ }
+
/**
* Adds a bookmark to Pinboard.
*
@@ -155,8 +173,8 @@ open class PinboardPoster() {
url: String,
description: String,
extended: String = "",
- tags: String = "",
- dt: String = "",
+ vararg tags: String = emptyArray(),
+ dt: ZonedDateTime = ZonedDateTime.now(),
replace: Boolean = true,
shared: Boolean = true,
toRead: Boolean = false
@@ -167,15 +185,15 @@ open class PinboardPoster() {
} else if (description.isBlank()) {
logger.severe("Please specify a valid description to pin: `$url`")
} else {
- val params = listOf(
- Pair("url", url),
- Pair("description", description),
- Pair("extended", extended),
- Pair("tags", tags),
- Pair("dt", dt),
- Pair("replace", yesNo(replace)),
- Pair("shared", yesNo(shared)),
- Pair("toread", yesNo(toRead))
+ val params = mapOf(
+ "url" to url,
+ "description" to description,
+ "extended" to extended,
+ "tags" to tags.joinToString(","),
+ "dt" to DateTimeFormatter.ISO_INSTANT.format(dt.withNano(0)),
+ "replace" to yesNo(replace),
+ "shared" to yesNo(shared),
+ "toread" to yesNo(toRead)
)
return executeMethod("posts/add", params)
}
@@ -198,13 +216,14 @@ open class PinboardPoster() {
if (!validateUrl(url)) {
logger.severe("Please specify a valid URL to delete.")
} else {
- return executeMethod("posts/delete", listOf(Pair("url", url)))
+ return executeMethod("posts/delete", mapOf("url" to url))
}
}
return false
}
+ @Throws(IOException::class)
internal fun parseMethodResponse(method: String, response: String) {
val factory = DocumentBuilderFactory.newInstance().apply {
isValidating = false
@@ -228,39 +247,40 @@ open class PinboardPoster() {
} else {
throw IOException("An error has occurred while executing $method.")
}
- } catch (e: Exception) {
+ } catch (e: org.xml.sax.SAXException) {
throw IOException("Could not parse $method response.", e)
+ } catch (e: IllegalArgumentException) {
+ throw IOException("Invalid input source for $method response", e)
}
}
private fun cleanEndPoint(method: String): String {
- return if (apiEndPoint.endsWith('/')) {
+ return if (apiEndPoint.last() == '/') {
"$apiEndPoint$method"
} else {
"$apiEndPoint/$method"
}
}
- private fun executeMethod(method: String, params: List>): Boolean {
+ private fun executeMethod(method: String, params: Map): Boolean {
try {
val apiUrl = cleanEndPoint(method).toHttpUrlOrNull()
if (apiUrl != null) {
val httpUrl = apiUrl.newBuilder().apply {
params.forEach {
- addQueryParameter(it.first, it.second)
+ addQueryParameter(it.key, it.value)
}
addQueryParameter("auth_token", apiToken)
}.build()
val request = Request.Builder().url(httpUrl).build()
- val result = client.newCall(request).execute()
- val response = result.body?.string()
-
- if (response != null) {
- if (response.contains("done")) {
- return true
- } else {
- parseMethodResponse(method, response)
+ client.newCall(request).execute().use { result ->
+ result.body?.string()?.let { response ->
+ if (response.contains("done")) {
+ return true
+ } else {
+ parseMethodResponse(method, response)
+ }
}
}
} else {
diff --git a/src/test/kotlin/net/thauvin/erik/pinboard/PinboardPosterTest.kt b/src/test/kotlin/net/thauvin/erik/pinboard/PinboardPosterTest.kt
index 0c724c7..a44cf25 100644
--- a/src/test/kotlin/net/thauvin/erik/pinboard/PinboardPosterTest.kt
+++ b/src/test/kotlin/net/thauvin/erik/pinboard/PinboardPosterTest.kt
@@ -1,7 +1,7 @@
/*
* PinboardPosterTest.kt
*
- * Copyright (c) 2017-2021, Erik C. Thauvin (erik@thauvin.net)
+ * Copyright (c) 2017-2023, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,20 +32,20 @@
package net.thauvin.erik.pinboard
-import org.testng.Assert.assertFalse
-import org.testng.Assert.assertTrue
-import org.testng.Assert.expectThrows
+import org.testng.Assert.*
import org.testng.annotations.Test
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Paths
-import java.util.Properties
+import java.time.ZonedDateTime
+import java.util.*
import java.util.logging.Level
class PinboardPosterTest {
- private val url = "http://www.foo.com/"
+ private val url = "http://www.example.com/?random=" + (1000..10000).random()
private val desc = "This is a test."
private val localProps = Paths.get("local.properties")
+ private val isCi = "true" == System.getenv("CI")
@Test
fun testAddPin() {
@@ -61,10 +61,42 @@ class PinboardPosterTest {
// assertFalse(poster.addPin(url, desc), "apiToken: ${poster.apiToken}")
poster = PinboardPoster(localProps)
- poster.logger.level = Level.FINE
+ if (!isCi) {
+ poster.logger.level = Level.FINE
+ }
assertTrue(poster.addPin(url, desc), "apiToken: ${Constants.ENV_API_TOKEN}")
}
+ @Test
+ fun testAddPinConfig() {
+ val poster = PinboardPoster(localProps)
+ if (!isCi) {
+ poster.logger.level = Level.FINE
+ }
+
+ var config = PinConfig.Builder().url(url).description(desc).extended("extra")
+
+ assertTrue(poster.addPin(config.build()), "apiToken: ${Constants.ENV_API_TOKEN}")
+
+ config = config.tags("foo", "bar")
+ assertTrue(poster.addPin(config.build()), "tags(foo,bar)")
+
+ config = config.shared(false)
+ assertTrue(poster.addPin(config.build()), "shared(false)")
+
+ try {
+ assertFalse(poster.addPin(config.replace(false).build()))
+ } catch (e: IOException) {
+ assertTrue(e.message!!.contains("item already exists"))
+ }
+
+ config = config.replace(true).toRead(true)
+ assertTrue(poster.addPin(config.build()), "toRead(true)")
+
+ config = config.dt(ZonedDateTime.now())
+ assertTrue(poster.addPin(config.build()), "dt(now)")
+ }
+
@Test
fun testDeletePin() {
val props = if (Files.exists(localProps)) {
@@ -84,8 +116,9 @@ class PinboardPosterTest {
assertFalse(poster.deletePin(url), "apiEndPoint: ")
poster = PinboardPoster(localProps, Constants.ENV_API_TOKEN)
- poster.logger.level = Level.FINE
-
+ if (!isCi) {
+ poster.logger.level = Level.FINE
+ }
poster.apiEndPoint = Constants.API_ENDPOINT
assertTrue(poster.deletePin(url), "apiEndPoint: ${Constants.API_ENDPOINT}")
diff --git a/updatewrappers.sh b/updatewrappers.sh
old mode 100644
new mode 100755
index a79d31e..a8b90d8
--- a/updatewrappers.sh
+++ b/updatewrappers.sh
@@ -9,7 +9,7 @@ declare -a dirs=(
"${PWD##*/}"
"samples/java"
"samples/kotlin")
-java8=true
+java8=false
###
@@ -25,7 +25,6 @@ then
export PATH="$(cygpath "$JAVA_HOME")/bin:$PATH"
fi
-kVer=$(kobaltw --version | awk '{print substr($2, 1, length($2)-1)}')
updateWrappers() {
curVer="$(gradle --version | awk '/Gradle/ {print $2}')"
if [ -d gradle ]; then
@@ -36,16 +35,6 @@ updateWrappers() {
echo -e " Gradle $curVer UP-TO-DATE"
fi
fi
- if [ -d kobalt ]; then
- kw=$(cut -d "=" -f 2 kobalt/wrapper/kobalt-wrapper.properties)
- if [ "$kw" = "$kVer" ]
- then
- echo -e " Kobalt $kw UP-TO-DATE"
- else
- echo -e "kobalt.version=$kVer" > kobalt/wrapper/kobalt-wrapper.properties
- echo -e " Kobalt $kVer ${green}UPDATED${std}"
- fi
- fi
}
echo -e "Updating wrappers..."