Initial Import

This commit is contained in:
Paul Campbell 2020-03-28 20:55:16 +00:00
commit 83df2cc6cc
13 changed files with 454 additions and 0 deletions

41
.github/GitHub-Actions.org vendored Normal file
View 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
View 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

Binary file not shown.

28
.github/settings.xml vendored Normal file
View 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
View 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
View 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
View 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

52
README.md Normal file
View file

@ -0,0 +1,52 @@
# File Reader/Writer
![Sonatype Nexus (Release)](https://img.shields.io/nexus/r/https/oss.sonatype.org/net.kemitix/file-reader-writer.svg?style=for-the-badge)
![Maven Central](https://img.shields.io/maven-central/v/net.kemitix/file-reader-writer.svg?style=for-the-badge)
Simple wrapper for the static methods `Files.readAllLines` and `Files.write`,
bringing into simple classes that can be injected into code using Dependency
Injection allowing them to be mocked during testing without touching the real
filesystem.
## Assumptions
* All files will be read and written in `ÙTF-8`.
* When reading a file lines breaks will be replaced by the newline character.
* When writing a file it will be truncated first.
## Usage
### Jakarta EE
```java
@Produces
FileReaderWriter fileReaderWriter() {
return new FileReaderWriter();
}
@Produces
FileReader fileReader() {
return new FileReaderWriter();
}
@Produces
FileWriter fileWriter() {
return new FileReaderWriter();
}
```
### Spring
```java
@Bean
FileReaderWriter fileReaderWriter() {
return new FileReaderWriter();
}
@Bean
FileReader fileReader() {
return new FileReaderWriter();
}
@Bean
FileWriter fileWriter() {
return new FileReaderWriter();
}
```

57
pom.xml Normal file
View file

@ -0,0 +1,57 @@
<?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>file-reader-writer</artifactId>
<version>DEV-SNAPSHOT</version>
<properties>
<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>
<pitest.skip>true</pitest.skip>
</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-jdk-11:${kemitix-maven-tiles.version}</tile>
<tile>net.kemitix.checkstyle:tile:${kemitix-checkstyle-ruleset.version}</tile>
</tiles>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,17 @@
package net.kemitix.files;
import java.io.File;
import java.io.IOException;
public interface FileReader {
/**
* Reads the content from the file path.
*
* <p>File content will be read using UTF-8 encoding and line endings will
* be replaced with a newline (\n).</p>
*
* @param file the file to read
* @throws IOException if there is an error.
*/
String read(File file) throws IOException;
}

View file

@ -0,0 +1,36 @@
package net.kemitix.files;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
public class FileReaderWriter implements FileReader, FileWriter {
private static final String NEWLINE = "\n";
@Override
public String read(final File file) throws IOException {
return String.join(NEWLINE,
Files.readAllLines(file.toPath(), StandardCharsets.UTF_8));
}
@Override
public void write(
final File file,
final String content
) throws IOException {
if (!file.exists()) {
try {
file.createNewFile();
} catch (final IOException e) {
throw new IOException("Could not create file", e);
}
}
Files.write(file.toPath(),
content.getBytes(StandardCharsets.UTF_8),
StandardOpenOption.TRUNCATE_EXISTING
);
}
}

View file

@ -0,0 +1,21 @@
package net.kemitix.files;
import java.io.File;
import java.io.IOException;
public interface FileWriter {
/**
* Writes the content to the file path, replacing any existing file.
*
* <p>File content will be written using UTF-8 encoding.</p>
*
* @param file the file to write
* @param content the content to write
*/
void write(
File file,
String content
) throws IOException;
}

View file

@ -0,0 +1,70 @@
package net.kemitix.files;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
public class FileReaderWriterTests {
private final String line1 = UUID.randomUUID().toString();
private final String line2 = UUID.randomUUID().toString();
private final String body = line1 + "\n" + line2;
private final FileWriter writer = new FileReaderWriter();
private final FileReader reader = new FileReaderWriter();
@TempDir
Path directory;
private File file;
@BeforeEach
void setUp() {
file = directory.resolve(UUID.randomUUID().toString())
.toFile();
}
@Test
@DisplayName("Create a new file then read it again")
public void readTheNewlyCreatedFile() throws IOException {
//when
writer.write(file, body);
final String read = reader.read(file);
//then
assertThat(read).isEqualTo(body);
}
@Test
@DisplayName("Replace an existing file then read it again")
public void readTheReplacedFile() throws IOException {
//given
writer.write(file, "Original file content");
//when
writer.write(file, body);
final String read = reader.read(file);
//then
assertThat(read).isEqualTo(body);
}
@Test
@DisplayName("When write to directory does not exist then throw exception")
public void writeToMissingDirThrows() throws IOException {
//given
directory.toFile().setReadOnly();
//then
try {
assertThatExceptionOfType(IOException.class)
.isThrownBy(() ->
writer.write(file, body))
.withMessage("Could not create file");
} finally {
directory.toFile().setWritable(true);
}
}
}