Initial import
This commit is contained in:
parent
865b7ed1d5
commit
9929bfe5e1
11 changed files with 410 additions and 0 deletions
41
.github/GitHub-Actions.org
vendored
Normal file
41
.github/GitHub-Actions.org
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
* Deploying using Github Actions
|
||||||
|
|
||||||
|
** Actions definition: workflow/sonatype-deploy.yml
|
||||||
|
|
||||||
|
When a GitHub Release is created, usually from a tag, this action will trigger.
|
||||||
|
|
||||||
|
Using JDK8 the software will be packaged, including running any tests.
|
||||||
|
|
||||||
|
Then the Deploy script will sign the created artifacts then deploy them according to the distributionManagement configuration in the `pom.xml`.
|
||||||
|
|
||||||
|
** Deploy Script
|
||||||
|
|
||||||
|
Uses a signing key provided from the GitHub Actions Secrets as an environment variable to sign the artifact(s) before they are then deployed.
|
||||||
|
|
||||||
|
*** Inputs
|
||||||
|
|
||||||
|
**** DEPLOY_PROJECTS (optional)
|
||||||
|
|
||||||
|
An optional list of modules in a multi-module project to be deployed. If this value is not specified, then all projects will be deployed.
|
||||||
|
|
||||||
|
** Maven Configuration
|
||||||
|
|
||||||
|
Picks up the credentials from Environment variables for authenticating both with GPG and with the target deployment server (e.g. sonatype-nexus).
|
||||||
|
|
||||||
|
*** Inputs
|
||||||
|
|
||||||
|
**** NEXUS_USERNAME
|
||||||
|
|
||||||
|
The username for your account on the deployment server.
|
||||||
|
|
||||||
|
**** NEXUS_PASSWORD
|
||||||
|
|
||||||
|
The password for your account on the deployement server.
|
||||||
|
|
||||||
|
**** GPG_KEYNAME
|
||||||
|
|
||||||
|
The key to use when signing.
|
||||||
|
|
||||||
|
**** GPG_PASSPHRASE
|
||||||
|
|
||||||
|
The passphrase to unlock the key to use when signing.
|
53
.github/NOTES
vendored
Normal file
53
.github/NOTES
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
Add subkeys:
|
||||||
|
|
||||||
|
????
|
||||||
|
|
||||||
|
Publish:
|
||||||
|
|
||||||
|
gpg --send-keys --keyserver keyserver.ubuntu.com $KEYID
|
||||||
|
gpg --send-keys --keyserver pgp.mit.edu $KEYID
|
||||||
|
gpg --send-keys --keyserver pool.sks-keyservers.net $KEYID
|
||||||
|
|
||||||
|
Backup:
|
||||||
|
|
||||||
|
gpg --export --armor pcampbell@kemitix.net > gpg-key-backup.asc
|
||||||
|
gpg --export-secret-keys --armor pcampbell@kemitix.net >> gpg-key-backup.asc
|
||||||
|
|
||||||
|
Export sub-keys:
|
||||||
|
|
||||||
|
gpg --export-secret-subkeys pcampbell@kemitix.net > subkeys
|
||||||
|
|
||||||
|
Remove master keys:
|
||||||
|
|
||||||
|
gpg --delete-secret-key pcampbell@kemitix.net
|
||||||
|
|
||||||
|
Import sub-keys and clean up:
|
||||||
|
|
||||||
|
gpg --import subkeys
|
||||||
|
|
||||||
|
shred --remove subkeys
|
||||||
|
|
||||||
|
Delete any encryption subkeys:
|
||||||
|
|
||||||
|
gpg --edit-key pcampbell@kemitix.net
|
||||||
|
|
||||||
|
2
|
||||||
|
delkey
|
||||||
|
save
|
||||||
|
|
||||||
|
Change passphrase:
|
||||||
|
|
||||||
|
gpg --edit-key pcampbell@kemitix.net
|
||||||
|
passwd
|
||||||
|
save
|
||||||
|
|
||||||
|
Export keys:
|
||||||
|
|
||||||
|
gpg --export --armor pcampbell@kemitix.net > codesigning.asc
|
||||||
|
gpg --export-secret-keys --armor pcampbell@kemitix.net >> codesigning.asc
|
||||||
|
|
||||||
|
Encrypt keys:
|
||||||
|
|
||||||
|
gpg --symmetric --cipher-algo AES256 codesigning.asc
|
||||||
|
|
||||||
|
shred codesigning.asc
|
BIN
.github/codesigning.asc.gpg
vendored
Normal file
BIN
.github/codesigning.asc.gpg
vendored
Normal file
Binary file not shown.
28
.github/settings.xml
vendored
Normal file
28
.github/settings.xml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
|
||||||
|
<servers>
|
||||||
|
<server>
|
||||||
|
<id>sonatype-nexus-snapshots</id>
|
||||||
|
<username>${env.NEXUS_USERNAME}</username>
|
||||||
|
<password>${env.NEXUS_PASSWORD}</password>
|
||||||
|
</server>
|
||||||
|
<server>
|
||||||
|
<id>sonatype-nexus-staging</id>
|
||||||
|
<username>${env.NEXUS_USERNAME}</username>
|
||||||
|
<password>${env.NEXUS_PASSWORD}</password>
|
||||||
|
</server>
|
||||||
|
</servers>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>gpg-sign</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<gpg.executable>gpg</gpg.executable>
|
||||||
|
<gpg.keyname>${env.GPG_KEYNAME}</gpg.keyname>
|
||||||
|
<gpg.passphrase>${env.GPG_PASSPHRASE}</gpg.passphrase>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</settings>
|
25
.github/workflows/maven-build.yml
vendored
Normal file
25
.github/workflows/maven-build.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# This workflow will build a Java project with Maven
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||||
|
|
||||||
|
name: Java CI with Maven
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: '*'
|
||||||
|
pull_request:
|
||||||
|
branches: '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java: [ 8, 11, 13 ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK ${{ matrix.java }}
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: ${{ matrix.java }}
|
||||||
|
- name: Build with Maven
|
||||||
|
run: mvn -B install
|
38
.github/workflows/sonatype-deploy.yml
vendored
Normal file
38
.github/workflows/sonatype-deploy.yml
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
name: Deploy to Sonatype Nexus
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 1.8
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 1.8
|
||||||
|
- name: Build with Maven
|
||||||
|
run: mvn -B install
|
||||||
|
- name: Nexus Repo Publish
|
||||||
|
run: |
|
||||||
|
gpg --quiet \
|
||||||
|
--batch \
|
||||||
|
--yes \
|
||||||
|
--decrypt \
|
||||||
|
--passphrase="${{ secrets.GPG_PASSPHRASE }}" \
|
||||||
|
--output codesigning.asc \
|
||||||
|
.github/codesigning.asc.gpg
|
||||||
|
gpg --batch \
|
||||||
|
--fast-import codesigning.asc
|
||||||
|
mvn --settings .github/settings.xml \
|
||||||
|
-Dskip-Tests=true \
|
||||||
|
-P release \
|
||||||
|
-B \
|
||||||
|
deploy
|
||||||
|
env:
|
||||||
|
NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
|
||||||
|
NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
|
||||||
|
GPG_KEYNAME: ${{ secrets.GPG_KEYNAME }}
|
||||||
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
*.jqwik-database*
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
|
||||||
|
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
|
||||||
|
!/.mvn/wrapper/maven-wrapper.jar
|
37
README.md
Normal file
37
README.md
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# List Head/Tail
|
||||||
|
|
||||||
|
![Sonatype Nexus (Release)](https://img.shields.io/nexus/r/https/oss.sonatype.org/net.kemitix/list-head-tail.svg?style=for-the-badge)
|
||||||
|
![Maven Central](https://img.shields.io/maven-central/v/net.kemitix/list-head-tail.svg?style=for-the-badge)
|
||||||
|
|
||||||
|
Provides a `head()` and `tail()` implementation for `List<>` objects in Java.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```java
|
||||||
|
import net.kemitix.list.HeadTail;
|
||||||
|
import java.util.List;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
class Usage {
|
||||||
|
List<String> list = Arrays.asList("a", "b", "c");
|
||||||
|
Optional<String> head = HeadTail.head(list); // head()
|
||||||
|
assertThat(head).contains("a");
|
||||||
|
List<String> tail = HeadTail.tail(list); // tail()
|
||||||
|
assertThat(tail).containsExactly("b", "c");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Statically importing the `head()` and `tail()` methods will be more
|
||||||
|
readable and idiomatically FP.
|
||||||
|
|
||||||
|
```java
|
||||||
|
import static net.kemitix.list.HeadTail.*;
|
||||||
|
import java.util.List;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
class Usage {
|
||||||
|
List<String> list = Arrays.asList("a", "b", "c");
|
||||||
|
Optional<String> head = head(list); // head()
|
||||||
|
assertThat(head).contains("a");
|
||||||
|
List<String> tail = tail(list); // tail()
|
||||||
|
assertThat(tail).containsExactly("b", "c");
|
||||||
|
}
|
||||||
|
```
|
59
pom.xml
Normal file
59
pom.xml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>net.kemitix</groupId>
|
||||||
|
<artifactId>kemitix-parent</artifactId>
|
||||||
|
<version>5.3.0</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>list-head-tail</artifactId>
|
||||||
|
<version>DEV-SNAPSHOT</version>
|
||||||
|
<inceptionYear>2020</inceptionYear>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
<tiles-maven-plugin.version>2.16</tiles-maven-plugin.version>
|
||||||
|
<kemitix-maven-tiles.version>2.5.0</kemitix-maven-tiles.version>
|
||||||
|
<kemitix-checkstyle-ruleset.version>5.4.0</kemitix-checkstyle-ruleset.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.6.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.15.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.repaint.maven</groupId>
|
||||||
|
<artifactId>tiles-maven-plugin</artifactId>
|
||||||
|
<version>${tiles-maven-plugin.version}</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<tiles>
|
||||||
|
<tile>net.kemitix.tiles:all:${kemitix-maven-tiles.version}</tile>
|
||||||
|
<tile>net.kemitix.checkstyle:tile:${kemitix-checkstyle-ruleset.version}</tile>
|
||||||
|
</tiles>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
62
src/main/java/net/kemitix/list/HeadTail.java
Normal file
62
src/main/java/net/kemitix/list/HeadTail.java
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Paul Campbell
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all copies
|
||||||
|
* or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.kemitix.list;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a simple implementation of head() and tail() for {@link List}s.
|
||||||
|
*/
|
||||||
|
public interface HeadTail {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first item in the list as an {@link Optional}.
|
||||||
|
*
|
||||||
|
* @param list the list
|
||||||
|
* @param <X> the type of the lists contents
|
||||||
|
* @return an Optional containing the first item in the list, or empty if
|
||||||
|
* the list is empty.
|
||||||
|
*/
|
||||||
|
static <X> Optional<X> head(final List<X> list) {
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(list.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list, minus the first item.
|
||||||
|
*
|
||||||
|
* @param list the list
|
||||||
|
* @param <X> the type of the lists contents
|
||||||
|
* @return a view of the list starting with the second item, or an empty
|
||||||
|
* list if the original list has less than two items.
|
||||||
|
*/
|
||||||
|
static <X> List<X> tail(final List<X> list) {
|
||||||
|
if (list.size() < 1) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return list.subList(1, list.size());
|
||||||
|
}
|
||||||
|
}
|
51
src/test/java/net/kemitix/list/HeadTailTest.java
Normal file
51
src/test/java/net/kemitix/list/HeadTailTest.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package net.kemitix.list;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class HeadTailTest {
|
||||||
|
|
||||||
|
private String headValue = "1-" + UUID.randomUUID().toString();
|
||||||
|
private String secondValue = "2-" + UUID.randomUUID().toString();
|
||||||
|
private String thirdValue = "3-" + UUID.randomUUID().toString();
|
||||||
|
private List<String> emptyList = Collections.emptyList();
|
||||||
|
private List<String> singletonList = Collections.singletonList(headValue);
|
||||||
|
private List<String> aList = Arrays.asList(
|
||||||
|
headValue, secondValue, thirdValue
|
||||||
|
);
|
||||||
|
private List<String> tailValue = Arrays.asList(
|
||||||
|
secondValue, thirdValue
|
||||||
|
);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headOfAnEmptyListIsEmpty() {
|
||||||
|
assertThat(HeadTail.head(emptyList)).isEmpty();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void headOfASingletonListIsTheItem() {
|
||||||
|
assertThat(HeadTail.head(singletonList)).contains(headValue);
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void headOfAListIsTheFirstItem() {
|
||||||
|
assertThat(HeadTail.head(aList)).contains(headValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tailOfAnEmptyListIsEmpty() {
|
||||||
|
assertThat(HeadTail.tail(emptyList)).isEmpty();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void tailOfASingletonListIsEmpty() {
|
||||||
|
assertThat(HeadTail.tail(singletonList)).isEmpty();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void tailOfAListIsMinusTheHead() {
|
||||||
|
assertThat(HeadTail.tail(aList)).isEqualTo(tailValue);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue