diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100755 index 08ebbb6..0000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100755 index 42fa4da..0000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip \ No newline at end of file diff --git a/Jenkinsfile.groovy b/Jenkinsfile.groovy index 443c1a9..f9bfea5 100644 --- a/Jenkinsfile.groovy +++ b/Jenkinsfile.groovy @@ -1,60 +1,66 @@ +final String publicRepo = 'https://github.com/kemitix/' final String mvn = "mvn --batch-mode --update-snapshots --errors" -final dependenciesSupportJDK = 9 +final dependenciesSupportJDK = 10 pipeline { agent any stages { - stage('release != SNAPSHOT') { - // checks that the pom version is not a SNAPSHOT when the current branch is a release - when { - expression { - (branchStartsWith('release/')) && - (readMavenPom(file: 'pom.xml').version).contains("SNAPSHOT") - } - } - steps { - error("Build failed because SNAPSHOT version: [" + env.GIT_BRANCH + "]") - } - } stage('Build & Test') { steps { - withMaven(maven: 'maven', jdk: 'JDK LTS') { + withMaven(maven: 'maven', jdk: 'JDK 1.8') { sh "${mvn} clean compile checkstyle:checkstyle pmd:pmd test" - jacoco exclusionPattern: '**/*{Test|IT|Main|Application|Immutable}.class' + // PMD to Jenkins pmd canComputeNew: false, defaultEncoding: '', healthy: '', pattern: '', unHealthy: '' - step([$class : 'hudson.plugins.checkstyle.CheckStylePublisher', - pattern : '**/target/checkstyle-result.xml', - healthy : '20', - unHealthy: '100']) + } + } + } + stage('Report Coverage') { + steps { + withMaven(maven: 'maven', jdk: 'JDK 1.8') { + // Code Coverage to Jenkins + jacoco exclusionPattern: '**/*{Test|IT|Main|Application|Immutable}.class' + } + } + } + stage('Report Checkstyle') { + steps { + withMaven(maven: 'maven', jdk: 'JDK 1.8') { + // Checkstyle to Jenkins + step([$class: 'hudson.plugins.checkstyle.CheckStylePublisher', + pattern: '**/target/checkstyle-result.xml', + healthy:'20', + unHealthy:'100']) } } } stage('Verify & Install') { steps { - withMaven(maven: 'maven', jdk: 'JDK LTS') { + withMaven(maven: 'maven', jdk: 'JDK 1.8') { sh "${mvn} -DskipTests install" } } } - stage('SonarQube (gitlab only)') { - when { expression { isPublished() } } + stage('SonarQube (published)') { + when { expression { isPublished(publicRepo) } } steps { withSonarQubeEnv('sonarqube') { - withMaven(maven: 'maven', jdk: 'JDK LTS') { + withMaven(maven: 'maven', jdk: 'JDK 1.8') { sh "${mvn} org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905:sonar" } } } } - stage('Deploy (release on gitlab)') { + stage('Deploy (published release branch)') { when { expression { - (branchStartsWith('release/') && isPublished()) + (isReleaseBranch() && + isPublished(publicRepo) && + notSnapshot()) } } steps { - withMaven(maven: 'maven', jdk: 'JDK LTS') { - sh "${mvn} deploy --activate-profiles release -DskipTests=true" + withMaven(maven: 'maven', jdk: 'JDK 1.8') { + sh "${mvn} --activate-profiles release deploy" } } } @@ -77,14 +83,22 @@ pipeline { } } -private boolean branchStartsWith(String branchName) { +private boolean isReleaseBranch() { + return branchStartsWith('release/') +} + +private boolean branchStartsWith(final String branchName) { startsWith(env.GIT_BRANCH, branchName) } -private boolean isPublished() { - startsWith(env.GIT_URL, 'https://') +private boolean isPublished(final String repo) { + startsWith(env.GIT_URL, repo) } -private boolean startsWith(String value, String match) { +private static boolean startsWith(final String value, final String match) { value != null && value.startsWith(match) } + +private boolean notSnapshot() { + return !(readMavenPom(file: 'pom.xml').version).contains("SNAPSHOT") +} diff --git a/mvnw b/mvnw deleted file mode 100755 index 961a825..0000000 --- a/mvnw +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - 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 - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - 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" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar" - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - wget "$jarUrl" -O "$wrapperJarPath" - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - curl -o "$wrapperJarPath" "$jarUrl" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100755 index 830073a..0000000 --- a/mvnw.cmd +++ /dev/null @@ -1,161 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar" -FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - echo Found %WRAPPER_JAR% -) else ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" - echo Finished downloading %WRAPPER_JAR% -) -@REM End of extension - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index ac9ad08..12e5d87 100644 --- a/pom.xml +++ b/pom.xml @@ -6,24 +6,26 @@ net.kemitix gitdb - 0.1.0-SNAPSHOT + DEV-SNAPSHOT 8 - 2.10 - 0.8.1 + 2.12 + 0.9.0 4.1.1 - 2.21.0 + 2.22.0 1.2.0 1.4.2 - 0.5 - 1.16.20 - 4.11.0.201803080745-r + 0.7 + 1.18.2 + 5.0.2.201807311906-r 5.2.0 - 3.10.0 - 0.8.0 - 2.18.3 + 3.11.1 + 0.11.0 + 2.21.0 0.9.0 + 0.7.0 + net.kemitix.gitdb @@ -37,6 +39,11 @@ mon ${mon.version} + + net.kemitix + conditional + ${conditional.version} + com.github.zafarkhaja java-semver diff --git a/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java b/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java index 321c526..20e759e 100644 --- a/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java +++ b/src/main/java/net/kemitix/gitdb/impl/GitDBRepo.java @@ -92,7 +92,7 @@ class GitDBRepo { } private Result> streamTree(final Ref branchRef, final GitTreeReader treeFilter) { - return treeFilter.stream(branchRef); + return treeFilter.entries(branchRef); } /** diff --git a/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java b/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java index 76c82f7..9651601 100644 --- a/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java +++ b/src/main/java/net/kemitix/gitdb/impl/GitTreeReader.java @@ -26,7 +26,6 @@ import lombok.RequiredArgsConstructor; import net.kemitix.mon.result.Result; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; @@ -35,7 +34,6 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter; import java.util.Optional; import java.util.concurrent.Callable; -import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; @@ -57,56 +55,45 @@ class GitTreeReader { * @param branchRef the branch to read * @return a stream of key/value pairs as NamedRevBlobs */ - Result> stream(final Ref branchRef) { - final TreeWalk treeWalk = new TreeWalk(repository); + Result> entries(final Ref branchRef) { final RevWalk revWalk = new RevWalk(repository); - return Result.of(parseBranchCommit(branchRef, revWalk)) - .map(RevCommit::getTree) - .flatMap(addTreeTo(treeWalk)) - .peek(disableRecursion(treeWalk)) - .peek(setTreeFilter(treeWalk)) - .flatMap(streamMatching(treeWalk, revWalk)); + return Result.of(parseTree(branchRef, revWalk)) + .andThen(configureFilter()) + .andThen(buildStream(revWalk)); } - private Function>> streamMatching( - final TreeWalk treeWalk, - final RevWalk revWalk - ) { - return x -> Result.of(() -> { + private Callable parseTree(final Ref branchRef, final RevWalk revWalk) { + return () -> revWalk.parseCommit(branchRef.getObjectId()).getTree(); + } + + private Function> configureFilter() { + return tree -> () -> { + final TreeWalk treeWalk = new TreeWalk(repository); + treeWalk.addTree(tree); + treeWalk.setRecursive(false); + Optional.ofNullable(treeFilter) + .ifPresent(treeWalk::setFilter); + return treeWalk; + }; + } + + private Function>> buildStream(final RevWalk revWalk) { + return treeWalk -> () -> { final Stream.Builder builder = Stream.builder(); while (treeWalk.next()) { builder.add(namedRevBlob(treeWalk, revWalk)); } return builder.build(); - }); + }; } - private NamedRevBlob namedRevBlob(TreeWalk treeWalk, RevWalk revWalk) { + private NamedRevBlob namedRevBlob(final TreeWalk treeWalk, final RevWalk revWalk) { return new NamedRevBlob( treeWalk.getNameString(), revWalk.lookupBlob(treeWalk.getObjectId(0)), repository); } - private Consumer setTreeFilter(TreeWalk treeWalk) { - return x -> Optional.ofNullable(treeFilter).ifPresent(treeWalk::setFilter); - } - - private Consumer disableRecursion(TreeWalk treeWalk) { - return x -> treeWalk.setRecursive(false); - } - - private Function> addTreeTo(TreeWalk treeWalk) { - return tree -> Result.of(() -> { - treeWalk.addTree(tree); - return null; - }); - } - - private Callable parseBranchCommit(Ref branchRef, RevWalk revWalk) { - return () -> revWalk.parseCommit(branchRef.getObjectId()); - } - /** * Sets a path filter to limit the stream by. * diff --git a/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java b/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java index c9d6351..f1f8fb8 100644 --- a/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java +++ b/src/main/java/net/kemitix/gitdb/impl/HeadWriter.java @@ -27,6 +27,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import java.io.File; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -49,15 +50,38 @@ class HeadWriter { * @return the Ref of the new branch */ Result write(final String branchName, final ObjectId commitId) { - final Path branchRefPath = repository - .getDirectory() - .toPath() - .resolve(branchName) - .toAbsolutePath(); - final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8); - return Result.of(() -> { - Files.write(branchRefPath, commitIdBytes); - return repository.findRef(branchName); - }); + return writeRef(branchName, commitId, repository) + .flatMap(x -> findRef(branchName, repository)); + } + + private static Result writeRef( + final String branchName, + final ObjectId commitId, + final Repository repository + ) { + return Result.of(() -> + Files.write( + branchRefPath(branchName, repository).toAbsolutePath(), + commitIdBytes(commitId))); + } + + private static Result findRef(final String branchName, final Repository repository) { + return Result.of(() -> repository.findRef(branchName)); + } + + private static Path branchRefPath(final String branchName, final Repository repository) { + return gitDirPath(repository).resolve(branchName); + } + + private static byte[] commitIdBytes(final ObjectId commitId) { + return commitId.name().getBytes(StandardCharsets.UTF_8); + } + + private static Path gitDirPath(final Repository repository) { + return gitDir(repository).toPath(); + } + + private static File gitDir(final Repository repository) { + return repository.getDirectory(); } } diff --git a/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java b/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java index b2cc831..ac71878 100644 --- a/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java +++ b/src/main/java/net/kemitix/gitdb/impl/InitGitDBRepo.java @@ -23,22 +23,25 @@ package net.kemitix.gitdb.impl; import net.kemitix.gitdb.FormatVersion; import net.kemitix.mon.result.Result; +import net.kemitix.mon.result.WithResultContinuation; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.util.FS; import java.io.File; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.*; +import java.util.concurrent.Callable; + +import static net.kemitix.conditional.Condition.where; /** * Initialise a new GitDB Repo. * * @author Paul Campbell (pcampbell@kemitix.net) */ -class InitGitDBRepo { +final class InitGitDBRepo { private static final String INIT_MESSAGE = "Initialise GitDB v1"; private static final String INIT_USER = "GitDB"; @@ -47,80 +50,84 @@ class InitGitDBRepo { private static final String GIT_DB_VERSION = "GitDB.Version"; private static final String REFS_HEADS_FORMAT = "refs/heads/%s"; + private InitGitDBRepo() { + throw new UnsupportedOperationException(); + } + /** * Initialise a new GitDB repo. * * @param dbDir the directory to initialise the repo in + * @return a Result containing the created Repository */ - static Result create(final Path dbDir) { - final InitGitDBRepo initRepo = new InitGitDBRepo(); - return initRepo.validDbDir(dbDir.toFile()) + static Result create(final Path dbDir) { + return validDbDir(dbDir.toFile()) .peek(File::mkdirs) - .flatMap(dir -> { - try (Repository repository = RepositoryCache.FileKey.exact(dir, FS.DETECTED).open(false)) { - repository.create(true); - initRepo.createInitialBranchOnMaster(repository); - } catch (IOException e) { - return Result.error(e); + .map(InitGitDBRepo::exactDirectory) + .andThen(InitGitDBRepo::openRepository) + .thenWith(InitGitDBRepo::createRepoDirectory) + .thenWith(InitGitDBRepo::createInitialMasterBranch); + } + + private static Result validDbDir(final File dbDir) { + return Result.ok(dbDir) + .flatMap(InitGitDBRepo::isNotAFile) + .flatMap(InitGitDBRepo::ifExistsThenIsEmpty); + } + + private static Result isNotAFile(final File dbDir) { + return Result.ok(dbDir) + .thenWith(dir -> () -> where(dir.isFile()).thenThrow(new NotDirectoryException(dbDir.toString()))); + } + + private static Result ifExistsThenIsEmpty(final File dbDir) { + return Result.ok(dbDir) + .thenWith(dir -> () -> { + if (dir.exists()) { + try (DirectoryStream directoryStream = Files.newDirectoryStream(dbDir.toPath())) { + where(directoryStream.iterator().hasNext()) + .thenThrow(new DirectoryNotEmptyException(dbDir.toString())); + } } - return Result.ok(null); }); } - private Result validDbDir(final File dbDir) { - return Result.ok(dbDir) - .flatMap(this::verifyIsNotAFile) - .flatMap(this::isEmptyIfExists); + private static RepositoryCache.FileKey exactDirectory(final File dir) { + return RepositoryCache.FileKey.exact(dir, FS.DETECTED); } - private Result createInitialBranchOnMaster(final Repository repository) { - final GitDBRepo repo = new GitDBRepo(repository); - return new ValueWriter(repository) - .write(new FormatVersion().toBytes()) - .flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid)) - .flatMap(tid -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL)) - .flatMap(cid -> Result.of(() -> { - createBranch(repository, cid, MASTER); - return null; - })); + private static Callable openRepository(final RepositoryCache.FileKey fileKey) { + return () -> fileKey.open(false); } - private Result verifyIsNotAFile(final File dbDir) { - if (dbDir.isFile()) { - return Result.error(new NotDirectoryException(dbDir.toString())); - } - return Result.ok(dbDir); + private static WithResultContinuation createRepoDirectory(final Repository repository) { + return () -> repository.create(true); } - private Result isEmptyIfExists(final File dbDir) { - if (dbDir.exists()) { - return Result.of(() -> { - try (DirectoryStream directoryStream = Files.newDirectoryStream(dbDir.toPath())) { - if (directoryStream.iterator().hasNext()) { - throw new DirectoryNotEmptyException(dbDir.toString()); - } - } - return dbDir; - } - ); - } - return Result.ok(dbDir); + private static WithResultContinuation createInitialMasterBranch( + final Repository repository + ) { + return () -> { + final GitDBRepo repo = new GitDBRepo(repository); + new ValueWriter(repository) + .write(new FormatVersion().toBytes()) + .flatMap(oid -> repo.insertNewTree(GIT_DB_VERSION, oid)) + .flatMap(tid -> repo.initialCommit(tid, INIT_MESSAGE, INIT_USER, INIT_EMAIL)) + .flatMap(cid -> createBranch(repository, cid, MASTER)); + }; } - private Result createBranch( + private static Result createBranch( final Repository repository, final ObjectId commitId, final String branchName ) { final Path branchRefPath = branchRefPath(repository, branchName); final byte[] commitIdBytes = commitId.name().getBytes(StandardCharsets.UTF_8); - return Result.of(() -> { - Files.write(branchRefPath, commitIdBytes); - return null; - }); + return Result.of(() -> Files.write(branchRefPath, commitIdBytes)); } - private Path branchRefPath( + private static Path branchRefPath( final Repository repository, final String branchName ) { diff --git a/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java b/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java index 392e540..2a7df2a 100644 --- a/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java +++ b/src/main/java/net/kemitix/gitdb/impl/KeyRemover.java @@ -24,12 +24,15 @@ package net.kemitix.gitdb.impl; import lombok.RequiredArgsConstructor; import net.kemitix.mon.maybe.Maybe; import net.kemitix.mon.result.Result; +import net.kemitix.mon.result.WithResultContinuation; import org.eclipse.jgit.lib.*; -import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.stream.Stream; + +import static net.kemitix.conditional.Condition.where; /** * Remove Key from the Git Repository. @@ -51,12 +54,22 @@ class KeyRemover { Result> remove(final Ref branchRef, final String key) { final TreeFormatter treeFormatter = new TreeFormatter(); final AtomicBoolean removed = new AtomicBoolean(false); - new GitTreeReader(repository) - .stream(branchRef) - .peek(s -> s.peek(flagIfFound(key, removed)) - .filter(isNotKey(key)) - .forEach(addToTree(treeFormatter))); - return insertTree(treeFormatter).maybe(oi -> removed.get()); + return new GitTreeReader(repository) + .entries(branchRef) + .thenWith(entries -> addOthersToTree(key, treeFormatter, removed, entries)) + .flatMap(x -> insertTree(treeFormatter)) + .maybe(x -> removed.get()); + } + + private static WithResultContinuation> addOthersToTree( + final String key, + final TreeFormatter treeFormatter, + final AtomicBoolean removed, + final Stream entryStream) { + return () -> entryStream + .peek(flagIfFound(key, removed)) + .filter(isNotKey(key)) + .forEach(addToTree(treeFormatter)); } /** @@ -67,11 +80,8 @@ class KeyRemover { * @return a Consumer */ private static Consumer flagIfFound(final String key, final AtomicBoolean removed) { - return nvb -> { - if (nvb.getName().equals(key)) { - removed.set(true); - } - }; + return nvb -> where(nvb.getName().equals(key)) + .then(() -> removed.set(true)); } /** @@ -101,10 +111,8 @@ class KeyRemover { * @return the name of the tree object. */ private Result insertTree(final TreeFormatter treeFormatter) { - try (ObjectInserter inserter = repository.getObjectDatabase().newInserter()) { - return Result.ok(inserter.insert(treeFormatter)); - } catch (IOException e) { - return Result.error(e); - } + return Result.ok(repository.getObjectDatabase()) + .map(ObjectDatabase::newInserter) + .andThen(inserter -> () -> inserter.insert(treeFormatter)); } } diff --git a/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java b/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java index 0c7364b..30f20fc 100644 --- a/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java +++ b/src/main/java/net/kemitix/gitdb/impl/KeyWriter.java @@ -71,7 +71,7 @@ class KeyWriter { private Result getTreeFormatter(final Ref branchRef) { final TreeFormatter treeFormatter = new TreeFormatter(); final GitTreeReader gitTreeReader = new GitTreeReader(repository); - return gitTreeReader.stream(branchRef) + return gitTreeReader.entries(branchRef) .peek(s -> s.forEach(item -> treeFormatter.append(item.getName(), item.getRevBlob()))) .map(x -> treeFormatter); } diff --git a/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java b/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java index 9164a96..6ac5c17 100644 --- a/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java +++ b/src/main/java/net/kemitix/gitdb/impl/LocalGitDBImpl.java @@ -94,7 +94,7 @@ final class LocalGitDBImpl implements GitDB, LocalGitDB { .map(toLocalGitDB(userName, userEmailAddress)); } - private static Result gitOpen(Path dbDir) { + private static Result gitOpen(final Path dbDir) { try { return Result.ok(Git.open(dbDir.toFile())); } catch (IOException e) { @@ -112,13 +112,9 @@ final class LocalGitDBImpl implements GitDB, LocalGitDB { @Override public Result> branch(final String name) { - try { - return Result.invert(Maybe.maybe( - repository.findRef(name)) - .map(branchInit::apply)); - } catch (IOException e) { - return Result.error(e); - } + return Result.flatMapMaybe( + Result.of(() -> Maybe.maybe(repository.findRef(name))), + refMaybe -> Result.invert(refMaybe.map(branchInit))); } } diff --git a/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java b/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java index d8376b6..6d9260d 100644 --- a/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java +++ b/src/main/java/net/kemitix/gitdb/impl/NamedRevBlob.java @@ -30,8 +30,6 @@ import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevBlob; -import java.io.IOException; - /** * Represents the key/value pairs read from the tree. * @@ -52,13 +50,9 @@ class NamedRevBlob { * @return a string */ Result blobAsString() { - try { - return Result.ok(repository.open(revBlob.getId(), Constants.OBJ_BLOB)) - .map(ObjectLoader::getBytes) - .map(String::new); - } catch (IOException e) { - return Result.error(e); - } + return Result.of(() -> repository.open(revBlob.getId(), Constants.OBJ_BLOB)) + .map(ObjectLoader::getBytes) + .map(String::new); } } diff --git a/src/test/java/net/kemitix/gitdb/impl/InitGitDBRepoTest.java b/src/test/java/net/kemitix/gitdb/impl/InitGitDBRepoTest.java new file mode 100644 index 0000000..8bbec03 --- /dev/null +++ b/src/test/java/net/kemitix/gitdb/impl/InitGitDBRepoTest.java @@ -0,0 +1,18 @@ +package net.kemitix.gitdb.impl; + +import org.assertj.core.api.WithAssertions; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Constructor; + +class InitGitDBRepoTest implements WithAssertions { + + @Test + void utilityClassCannotBeInstantiated() throws NoSuchMethodException { + final Constructor constructor = InitGitDBRepo.class.getDeclaredConstructor(); + constructor.setAccessible(true); + assertThatCode(constructor::newInstance) + .hasCauseInstanceOf(UnsupportedOperationException.class); + } + +} \ No newline at end of file