diff --git a/.blaze/blaze.conf b/.blaze/blaze.conf
index 59fa83f0..86720313 100644
--- a/.blaze/blaze.conf
+++ b/.blaze/blaze.conf
@@ -1,7 +1,7 @@
blaze.dependencies = [
"com.fizzed:blaze-ssh",
"com.fizzed:blaze-jsync",
- "com.fizzed:blaze-public-project:4.7.0"
+ "com.fizzed:blaze-public-project:4.8.0"
]
java.source.version = 8
diff --git a/.blaze/blaze.java b/.blaze/blaze.java
index 818722ea..0f32bcb7 100644
--- a/.blaze/blaze.java
+++ b/.blaze/blaze.java
@@ -16,6 +16,7 @@
import com.fizzed.blaze.Contexts;
import static com.fizzed.blaze.Contexts.withBaseDir;
+import static com.fizzed.blaze.Systems.exec;
import com.fizzed.blaze.Task;
import com.fizzed.blaze.TaskGroup;
@@ -42,4 +43,13 @@ public void try_all() throws Exception {
Contexts.withBaseDir(".");
}
+ @Task(group="maintainers")
+ public void generate_poms() {
+ exec("java", "-jar", "blaze.jar", "--generate-maven-project", "-f", ".blaze/blaze.java")
+ .run();
+
+ exec("java", "-jar", "blaze.jar", "--generate-maven-project", "-f", "examples/blaze.java")
+ .run();
+ }
+
}
diff --git a/.blaze/pom.xml b/.blaze/pom.xml
index 5a73fc4c..5917339e 100644
--- a/.blaze/pom.xml
+++ b/.blaze/pom.xml
@@ -23,7 +23,7 @@
com.fizzed
blaze-core
- 2.10.0
+ 2.11.0
org.slf4j
@@ -48,7 +48,7 @@
com.fizzed
blaze-ivy
- 2.10.0
+ 2.11.0
org.apache.ivy
@@ -58,12 +58,17 @@
com.fizzed
blaze-ssh
- 2.10.0
+ 2.11.0
+
+
+ com.fizzed
+ blaze-jsync
+ 2.11.0
com.fizzed
blaze-public-project
- 4.7.0
+ 4.8.0
\ No newline at end of file
diff --git a/README.md b/README.md
index b0e21348..1ea59f4f 100644
--- a/README.md
+++ b/README.md
@@ -100,6 +100,7 @@ JVM languages.
- [Configuration and dependency management](docs/CONFIG.md)
- [Basic usage](docs/BASIC.md)
- [SSH plugin](docs/SSH.md)
+ - [JSYNC plugin](docs/JSYNC.md)
- [HTTP plugin](docs/HTTP.md)
- [Archive plugin](docs/ARCHIVE.md)
diff --git a/buildx-results.txt b/buildx-results.txt
index 327e369b..22b93393 100644
--- a/buildx-results.txt
+++ b/buildx-results.txt
@@ -3,8 +3,8 @@ Buildx Results
Cross platform tests based on https://github.com/fizzed/buildx
-Commit: 0a05b0a3eaab3af85f4e0f178fa722d9069e1b8e
-Date: 2025-11-30T17:37:44.302629266Z[UTC]
+Commit: b4d36d00f86db68091a7e2e41cf43aee14e90bd1
+Date: 2025-12-03T19:19:24.884536439Z[UTC]
jdk-25 (Zulu JDK 25.0.1 (Linux, x64, /usr/lib/jvm/zulu-jdk-25.0.1.8))...... success
jdk-21 (Zulu JDK 21.0.8 (Linux, x64, /usr/lib/jvm/zulu-jdk-21.0.8.9))...... success
@@ -35,12 +35,14 @@ freebsd-arm64 (FreeBSD 15)................................................. succ
freebsd-arm64 (FreeBSD 14)................................................. success
openbsd-x64 (OpenBSD 7.8).................................................. success
openbsd-arm64 (OpenBSD 7.8)................................................ success
-netbsd-x64 (NetBSD 10)..................................................... failed: Process exited with unexpected value (expected = [0->0]; actual = 1)
+netbsd-x64 (NetBSD 10)..................................................... success
+omnios-x64 (OmniOS 151056)................................................. success
+omnios-x64 (OmniOS 151046)................................................. success
Details =>
Job #0 for jdk-25 (Zulu JDK 25.0.1 (Linux, x64, /usr/lib/jvm/zulu-jdk-25.0.1.8))
- log file: .buildx-logs/1764523910571/job-0-jdk-25.log
+ log file: .buildx-logs/1764789258977/job-0-jdk-25.log
host:
os: linux
arch: x64
@@ -56,7 +58,7 @@ Job #0 for jdk-25 (Zulu JDK 25.0.1 (Linux, x64, /usr/lib/jvm/zulu-jdk-25.0.1.8))
status: success
Job #1 for jdk-21 (Zulu JDK 21.0.8 (Linux, x64, /usr/lib/jvm/zulu-jdk-21.0.8.9))
- log file: .buildx-logs/1764523910571/job-1-jdk-21.log
+ log file: .buildx-logs/1764789258977/job-1-jdk-21.log
host:
os: linux
arch: x64
@@ -72,7 +74,7 @@ Job #1 for jdk-21 (Zulu JDK 21.0.8 (Linux, x64, /usr/lib/jvm/zulu-jdk-21.0.8.9))
status: success
Job #2 for jdk-17 (Zulu JDK 17.0.16 (Linux, x64, /usr/lib/jvm/zulu-jdk-17.0.16.8))
- log file: .buildx-logs/1764523910571/job-2-jdk-17.log
+ log file: .buildx-logs/1764789258977/job-2-jdk-17.log
host:
os: linux
arch: x64
@@ -88,7 +90,7 @@ Job #2 for jdk-17 (Zulu JDK 17.0.16 (Linux, x64, /usr/lib/jvm/zulu-jdk-17.0.16.8
status: success
Job #3 for jdk-11 (Zulu JDK 11.0.28 (Linux, x64, /usr/lib/jvm/zulu-jdk-11.0.28.6))
- log file: .buildx-logs/1764523910571/job-3-jdk-11.log
+ log file: .buildx-logs/1764789258977/job-3-jdk-11.log
host:
os: linux
arch: x64
@@ -104,7 +106,7 @@ Job #3 for jdk-11 (Zulu JDK 11.0.28 (Linux, x64, /usr/lib/jvm/zulu-jdk-11.0.28.6
status: success
Job #4 for jdk-8 (Zulu JDK 8.0.462 (Linux, x64, /usr/lib/jvm/zulu-jdk-8.0.462.8))
- log file: .buildx-logs/1764523910571/job-4-jdk-8.log
+ log file: .buildx-logs/1764789258977/job-4-jdk-8.log
host:
os: linux
arch: x64
@@ -120,7 +122,7 @@ Job #4 for jdk-8 (Zulu JDK 8.0.462 (Linux, x64, /usr/lib/jvm/zulu-jdk-8.0.462.8)
status: success
Job #5 for linux-x64 (Ubuntu 22.04)
- log file: .buildx-logs/1764523910571/job-5-linux-x64.log
+ log file: .buildx-logs/1764789258977/job-5-linux-x64.log
host:
os: linux
arch: x64
@@ -139,7 +141,7 @@ Job #5 for linux-x64 (Ubuntu 22.04)
status: success
Job #6 for linux-x64 (Ubuntu 24.04)
- log file: .buildx-logs/1764523910571/job-6-linux-x64.log
+ log file: .buildx-logs/1764789258977/job-6-linux-x64.log
host: bmh-build-x64-linux-latest
os: linux
arch: x64
@@ -154,7 +156,7 @@ Job #6 for linux-x64 (Ubuntu 24.04)
status: success
Job #7 for linux-x64 (Ubuntu 20.04)
- log file: .buildx-logs/1764523910571/job-7-linux-x64.log
+ log file: .buildx-logs/1764789258977/job-7-linux-x64.log
host: bmh-build-x64-linux-baseline
os: linux
arch: x64
@@ -169,7 +171,7 @@ Job #7 for linux-x64 (Ubuntu 20.04)
status: success
Job #8 for linux-arm64 (Ubuntu 24.04)
- log file: .buildx-logs/1764523910571/job-8-linux-arm64.log
+ log file: .buildx-logs/1764789258977/job-8-linux-arm64.log
host: bmh-build-arm64-linux-latest
os: linux
arch: arm64
@@ -184,7 +186,7 @@ Job #8 for linux-arm64 (Ubuntu 24.04)
status: success
Job #9 for linux-arm64 (Ubuntu 20.04)
- log file: .buildx-logs/1764523910571/job-9-linux-arm64.log
+ log file: .buildx-logs/1764789258977/job-9-linux-arm64.log
host: bmh-build-arm64-linux-baseline
os: linux
arch: arm64
@@ -199,7 +201,7 @@ Job #9 for linux-arm64 (Ubuntu 20.04)
status: success
Job #10 for linux-riscv64 (Ubuntu 24.04)
- log file: .buildx-logs/1764523910571/job-10-linux-riscv64.log
+ log file: .buildx-logs/1764789258977/job-10-linux-riscv64.log
host: bmh-build-riscv64-linux-latest
os: linux
arch: riscv64
@@ -214,7 +216,7 @@ Job #10 for linux-riscv64 (Ubuntu 24.04)
status: success
Job #11 for alpine-x64 (Alpine 3.22)
- log file: .buildx-logs/1764523910571/job-11-alpine-x64.log
+ log file: .buildx-logs/1764789258977/job-11-alpine-x64.log
host: bmh-build-x64-alpine-latest
os: linux
arch: x64
@@ -229,7 +231,7 @@ Job #11 for alpine-x64 (Alpine 3.22)
status: success
Job #12 for alpine-x64 (Alpine 3.15)
- log file: .buildx-logs/1764523910571/job-12-alpine-x64.log
+ log file: .buildx-logs/1764789258977/job-12-alpine-x64.log
host: bmh-build-x64-alpine-baseline
os: linux
arch: x64
@@ -244,7 +246,7 @@ Job #12 for alpine-x64 (Alpine 3.15)
status: success
Job #13 for alpine-arm64 (Alpine 3.22)
- log file: .buildx-logs/1764523910571/job-13-alpine-arm64.log
+ log file: .buildx-logs/1764789258977/job-13-alpine-arm64.log
host: bmh-build-arm64-alpine-latest
os: linux
arch: arm64
@@ -259,7 +261,7 @@ Job #13 for alpine-arm64 (Alpine 3.22)
status: success
Job #14 for alpine-arm64 (Alpine 3.15)
- log file: .buildx-logs/1764523910571/job-14-alpine-arm64.log
+ log file: .buildx-logs/1764789258977/job-14-alpine-arm64.log
host: bmh-build-arm64-alpine-baseline
os: linux
arch: arm64
@@ -274,7 +276,7 @@ Job #14 for alpine-arm64 (Alpine 3.15)
status: success
Job #15 for alpine-riscv64 (Alpine 3.22)
- log file: .buildx-logs/1764523910571/job-15-alpine-riscv64.log
+ log file: .buildx-logs/1764789258977/job-15-alpine-riscv64.log
host: bmh-build-riscv64-alpine-latest
os: linux
arch: riscv64
@@ -289,7 +291,7 @@ Job #15 for alpine-riscv64 (Alpine 3.22)
status: success
Job #16 for macos-x64 (MacOS 15)
- log file: .buildx-logs/1764523910571/job-16-macos-x64.log
+ log file: .buildx-logs/1764789258977/job-16-macos-x64.log
host: bmh-build-x64-macos-latest
os: macos
arch: x64
@@ -303,7 +305,7 @@ Job #16 for macos-x64 (MacOS 15)
status: success
Job #17 for macos-x64 (MacOS 11)
- log file: .buildx-logs/1764523910571/job-17-macos-x64.log
+ log file: .buildx-logs/1764789258977/job-17-macos-x64.log
host: bmh-build-x64-macos-baseline
os: macos
arch: x64
@@ -317,7 +319,7 @@ Job #17 for macos-x64 (MacOS 11)
status: success
Job #18 for macos-arm64 (MacOS 15)
- log file: .buildx-logs/1764523910571/job-18-macos-arm64.log
+ log file: .buildx-logs/1764789258977/job-18-macos-arm64.log
host: bmh-build-arm64-macos-latest
os: macos
arch: arm64
@@ -331,7 +333,7 @@ Job #18 for macos-arm64 (MacOS 15)
status: success
Job #19 for macos-arm64 (MacOS 12)
- log file: .buildx-logs/1764523910571/job-19-macos-arm64.log
+ log file: .buildx-logs/1764789258977/job-19-macos-arm64.log
host: bmh-build-arm64-macos-baseline
os: macos
arch: arm64
@@ -345,7 +347,7 @@ Job #19 for macos-arm64 (MacOS 12)
status: success
Job #20 for windows-x64 (Windows 11)
- log file: .buildx-logs/1764523910571/job-20-windows-x64.log
+ log file: .buildx-logs/1764789258977/job-20-windows-x64.log
host: bmh-build-x64-windows-latest
os: windows
arch: x64
@@ -359,7 +361,7 @@ Job #20 for windows-x64 (Windows 11)
status: success
Job #21 for windows-x64 (Windows 10)
- log file: .buildx-logs/1764523910571/job-21-windows-x64.log
+ log file: .buildx-logs/1764789258977/job-21-windows-x64.log
host: bmh-build-x64-windows-baseline
os: windows
arch: x64
@@ -373,7 +375,7 @@ Job #21 for windows-x64 (Windows 10)
status: success
Job #22 for windows-arm64 (Windows 11)
- log file: .buildx-logs/1764523910571/job-22-windows-arm64.log
+ log file: .buildx-logs/1764789258977/job-22-windows-arm64.log
host: bmh-build-arm64-windows-latest
os: windows
arch: arm64
@@ -387,12 +389,12 @@ Job #22 for windows-arm64 (Windows 11)
status: success
Job #23 for freebsd-x64 (FreeBSD 15)
- log file: .buildx-logs/1764523910571/job-23-freebsd-x64.log
+ log file: .buildx-logs/1764789258977/job-23-freebsd-x64.log
host: bmh-build-x64-freebsd-latest
os: freebsd
arch: x64
- name: FreeBSD 15.0-ALPHA1
- uname: FreeBSD bmh-build-x64-freebsd15-1 15.0-ALPHA1 FreeBSD 15.0-ALPHA1 #0 stable/15-n280099-0b3d82579a01: Sat Sep 6 19:04:24 -00 2025 root@releng3.nyi.freebsd.org:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
+ name: FreeBSD 15.0-RELEASE
+ uname: FreeBSD bmh-build-x64-freebsd15-1 15.0-RELEASE FreeBSD 15.0-RELEASE releng/15.0-n280995-7aedc8de6446 GENERIC amd64
podman:
tags: [latest]
data:
@@ -401,7 +403,7 @@ Job #23 for freebsd-x64 (FreeBSD 15)
status: success
Job #24 for freebsd-x64 (FreeBSD 13)
- log file: .buildx-logs/1764523910571/job-24-freebsd-x64.log
+ log file: .buildx-logs/1764789258977/job-24-freebsd-x64.log
host: bmh-build-x64-freebsd-baseline
os: freebsd
arch: x64
@@ -415,12 +417,12 @@ Job #24 for freebsd-x64 (FreeBSD 13)
status: success
Job #25 for freebsd-arm64 (FreeBSD 15)
- log file: .buildx-logs/1764523910571/job-25-freebsd-arm64.log
+ log file: .buildx-logs/1764789258977/job-25-freebsd-arm64.log
host: bmh-build-arm64-freebsd-latest
os: freebsd
arch: arm64
- name: FreeBSD 15.0-BETA2
- uname: FreeBSD bmh-build-arm64-freebsd15-1 15.0-BETA2 FreeBSD 15.0-BETA2 releng/15.0-n280707-3edefa72bc4e GENERIC arm64
+ name: FreeBSD 15.0-RELEASE
+ uname: FreeBSD bmh-build-arm64-freebsd15-1 15.0-RELEASE FreeBSD 15.0-RELEASE releng/15.0-n280995-7aedc8de6446 GENERIC arm64
podman:
tags: [latest]
data:
@@ -429,7 +431,7 @@ Job #25 for freebsd-arm64 (FreeBSD 15)
status: success
Job #26 for freebsd-arm64 (FreeBSD 14)
- log file: .buildx-logs/1764523910571/job-26-freebsd-arm64.log
+ log file: .buildx-logs/1764789258977/job-26-freebsd-arm64.log
host: bmh-build-arm64-freebsd-baseline
os: freebsd
arch: arm64
@@ -443,7 +445,7 @@ Job #26 for freebsd-arm64 (FreeBSD 14)
status: success
Job #27 for openbsd-x64 (OpenBSD 7.8)
- log file: .buildx-logs/1764523910571/job-27-openbsd-x64.log
+ log file: .buildx-logs/1764789258977/job-27-openbsd-x64.log
host: bmh-build-x64-openbsd-latest
os: openbsd
arch: x64
@@ -457,7 +459,7 @@ Job #27 for openbsd-x64 (OpenBSD 7.8)
status: success
Job #28 for openbsd-arm64 (OpenBSD 7.8)
- log file: .buildx-logs/1764523910571/job-28-openbsd-arm64.log
+ log file: .buildx-logs/1764789258977/job-28-openbsd-arm64.log
host: bmh-build-arm64-openbsd-latest
os: openbsd
arch: arm64
@@ -471,7 +473,7 @@ Job #28 for openbsd-arm64 (OpenBSD 7.8)
status: success
Job #29 for netbsd-x64 (NetBSD 10)
- log file: .buildx-logs/1764523910571/job-29-netbsd-x64.log
+ log file: .buildx-logs/1764789258977/job-29-netbsd-x64.log
host: bmh-build-x64-netbsd-latest
os: netbsd
arch: x64
@@ -482,6 +484,34 @@ Job #29 for netbsd-x64 (NetBSD 10)
data:
container:
- status: failed
+ status: success
+
+Job #30 for omnios-x64 (OmniOS 151056)
+ log file: .buildx-logs/1764789258977/job-30-omnios-x64.log
+ host: bmh-build-x64-omnios-latest
+ os: solaris
+ arch: x64
+ name: OmniOS v11 r151056d
+ uname: SunOS bmh-build-x64-omnios25-1 5.11 omnios-r151056-9fd2b931e3 i86pc i386 i86pc
+ podman:
+ tags: [latest]
+ data:
+ container:
+
+ status: success
+
+Job #31 for omnios-x64 (OmniOS 151046)
+ log file: .buildx-logs/1764789258977/job-31-omnios-x64.log
+ host: bmh-build-x64-omnios-baseline
+ os: solaris
+ arch: x64
+ name: OmniOS v11 r151046ee
+ uname: SunOS bmh-build-x64-omnios23-1 5.11 omnios-r151046-7bb78e46aa i86pc i386 i86pc
+ podman:
+ tags: [baseline]
+ data:
+ container:
+
+ status: success
====================================================================================================
diff --git a/docs/JSYNC.md b/docs/JSYNC.md
new file mode 100644
index 00000000..4a8a7902
--- /dev/null
+++ b/docs/JSYNC.md
@@ -0,0 +1,123 @@
+Blaze by Fizzed
+=======================================
+
+## Jsync
+
+Add the following to your `blaze.conf` file to include extensive support for rsync-like functionality. You can synchronize
+files or directories between local and remote hosts (via SSH/SFTP). Blaze uses the excellent [Jsync](https://github.com/fizzed/jsync)
+library for the actual rsync functionality.
+
+You do not want to specify a version so Blaze will resolve the identical version to whatever `blaze-core` you're running with.
+
+ blaze.dependencies = [
+ "com.fizzed:blaze-ssh",
+ "com.fizzed:blaze-jsync"
+ ]
+
+### Volumes
+
+To abstract away the details of the remote filesystem, Blaze uses a concept of a `Volume`. A volume is a filesystem
+that can be accessed via SSH/SFTP or locally. Blaze comes with a `LocalVolume` implementation that represents the local filesystem.
+It also ships with an `SftpVolume` implementation that represents a remote filesystem via SFTP/SSH.
+
+### Example
+
+There is an example of using Jsync in the examples directory of the Blaze source code. To run it, you can use the following command
+in the root of this project directory:
+
+ java -jar blaze.jar examples/jsync.java --from /home/jjlauer/Downloads/example.iso --to bmh-build-x64-freebsd15-1:. --mode nest
+
+### Usage
+
+Here is an example of syncing a directory from one local directory to another, along with asking for verbose output and progress reporting.
+Instead of using the somewhat confusing "does this directory end with a slash?" syntax, you need to explicitly tell
+jsync what `mode` you want to use. The `MERGE` mode will take source dir and merge it into the target directory, so that
+target directory becomes the source directory. It's akin to adding a slash to the end of the source and target directories.
+The `NEST` mode will take the source directory and copy it into the target directory, so that the target directory becomes
+a subdirectory of the target directory.
+
+```java
+import static com.fizzed.blaze.jsync.Jsyncs.*;
+import com.fizzed.blaze.jsync.engine.JsyncMode;
+
+// ... other code
+
+jsync(localVolume("example/from-dir"), localVolume("example/to-dir"), JsyncMode.MERGE)
+ .verbose()
+ .progress()
+ .run();
+```
+
+There are also many other options available, such as specifying a filter, excluding files, etc. See the [Jsync javadocs
+and class for more information](https://github.com/fizzed/blaze/blob/master/blaze-jsync/src/main/java/com/fizzed/blaze/jsync/Jsync.java).
+
+```java
+import static com.fizzed.blaze.jsync.Jsyncs.*;
+import com.fizzed.blaze.jsync.engine.JsyncMode;
+
+// ... other code
+
+jsync(localVolume("example/from-dir"), localVolume("example/to-dir"), JsyncMode.MERGE)
+ .verbose()
+ .progress()
+ .parents()
+ .force()
+ .delete()
+ .skipPermissions()
+ .ignoreTimes()
+ .ignore(".git")
+ .run();
+```
+
+To sync from a remote host, you can use the `sftpVolume` method to create a volume that represents a remote filesystem.
+You can use this volume as the source, target, or both. Jsync supports synchronizing local-to-remote, remote-to-local,
+or even remote-to-remote (where the data flows thru the host you run it on).
+
+Jsync supports `sftpVolume` which will create the underlying SSH & SFTP session under the hood for you, or if you already
+have an SSH or SFTP sessions, you can pass those in directly and they will be used instead of creating new ones. This
+is significantly more efficient than creating a new SSH session for every sync, or if you are already doing other SSH
+or SFTP operations outside of using Jsync. To have Jsync create the SSH session for you, use the `sshVolume` method.
+
+```java
+import static com.fizzed.blaze.jsync.Jsyncs.*;
+import com.fizzed.blaze.jsync.engine.JsyncMode;
+
+// ... other code
+
+jsync(localVolume("example/from-dir"), sftpVolume("target-host.example.com", "example/to-dir"), JsyncMode.MERGE)
+ .verbose()
+ .progress()
+ .run();
+```
+
+Alternatively, here is an example where we will re-use an existing SSH session to sync from a remote host to a local directory.
+
+```java
+import static com.fizzed.blaze.SecureShells.sshConnect;
+
+// ... other code
+
+try (SshSession ssh = sshConnect("ssh://user@internal1").run()) {
+ jsync(sftpVolume(ssh, "example/from-dir"), localVolume("example"), JsyncMode.NEST)
+ .verbose()
+ .progress()
+ .run();
+}
+```
+
+Alternatively, here is an example where we will re-use an existing SSH and SFTP session to sync from a remote host to a local directory.
+
+```java
+import static com.fizzed.blaze.SecureShells.sshConnect;
+
+// ... other code
+
+try (SshSession ssh = sshConnect("ssh://user@internal1").run()) {
+ try (SshSftpSession sftp = sshSftp(session).run()) {
+ jsync(sftpVolume(ssh, sftp, "example/from-dir"), localVolume("example"), JsyncMode.NEST)
+ .verbose()
+ .progress()
+ .run();
+ }
+}
+```
diff --git a/examples/blaze.conf b/examples/blaze.conf
new file mode 100644
index 00000000..ec787f22
--- /dev/null
+++ b/examples/blaze.conf
@@ -0,0 +1,16 @@
+# to get IDE completion for all examples, we will include dependencies here for everything used
+blaze.dependencies = [
+ "com.fizzed:blaze-http",
+ "com.fizzed:blaze-ssh",
+ "com.fizzed:blaze-jsync",
+ # find_java example
+ "com.fizzed:jne:4.11.0",
+ # git example
+ "org.eclipse.jgit:org.eclipse.jgit:4.1.0.201509280440-r",
+ # grep example
+ "org.unix4j:unix4j-command:0.6",
+ # guave example
+ "com.google.guava:guava:18.0",
+ # undertow example
+ "io.undertow:undertow-core:1.3.3.Final"
+]
\ No newline at end of file
diff --git a/examples/blaze.java b/examples/blaze.java
new file mode 100644
index 00000000..0d11e49d
--- /dev/null
+++ b/examples/blaze.java
@@ -0,0 +1,7 @@
+public class blaze {
+
+ public void main() {
+ // empty on purpose
+ }
+
+}
diff --git a/examples/jsync.conf b/examples/jsync.conf
new file mode 100644
index 00000000..a73005e6
--- /dev/null
+++ b/examples/jsync.conf
@@ -0,0 +1,4 @@
+blaze.dependencies = [
+ "com.fizzed:blaze-ssh",
+ "com.fizzed:blaze-jsync"
+]
\ No newline at end of file
diff --git a/examples/jsync.java b/examples/jsync.java
new file mode 100644
index 00000000..d91727bf
--- /dev/null
+++ b/examples/jsync.java
@@ -0,0 +1,90 @@
+import com.fizzed.blaze.Config;
+import com.fizzed.blaze.Contexts;
+import com.fizzed.blaze.core.Verbosity;
+import com.fizzed.jsync.engine.JsyncMode;
+import com.fizzed.jsync.vfs.VirtualVolume;
+import org.slf4j.Logger;
+
+import java.nio.file.Paths;
+import java.util.NoSuchElementException;
+
+import static com.fizzed.blaze.jsync.Jsyncs.*;
+
+public class jsync {
+ final private Logger log = Contexts.logger();
+ final private Config config = Contexts.config();
+
+ public void main() throws Exception {
+ // simple for skipping this example in try_all.java
+ boolean in_try_all_example = config.flag("examples-try-all").getOr(false);
+ if (in_try_all_example) {
+ log.info("Skipping example in try_all.java");
+ return;
+ }
+
+ try {
+ final String from = this.config.value("from").get();
+ final String to = this.config.value("to").get();
+ final String modeStr = this.config.value("mode").get();
+ final JsyncMode mode = JsyncMode.valueOf(modeStr.toUpperCase());
+ final boolean verbose = this.config.flag("no-verbose").orElse(true);
+ final boolean progress = this.config.flag("no-progress").orElse(true);
+ final boolean parents = this.config.flag("parents").orElse(false);
+ final boolean force = this.config.flag("force").orElse(false);
+ final boolean delete = this.config.flag("delete").orElse(false);
+
+ final VirtualVolume fromVolume = this.detectVolume(from);
+ final VirtualVolume toVolume = this.detectVolume(to);
+
+ jsync(fromVolume, toVolume, mode)
+ .verbosity(verbose ? Verbosity.VERBOSE : Verbosity.DEFAULT)
+ .progress(progress)
+ .parents(parents)
+ .force(force)
+ .delete(delete)
+ .run();
+ } catch (NoSuchElementException e) {
+ this.printUsage();
+ System.exit(1);
+ }
+ }
+
+ public void printUsage() {
+ System.out.println("Usage: blaze examples/jsync.java --from --to [--mode ] [--no-verbose] [--no-progress] [--parents] [--force] [--delete]");
+ System.out.println();
+ System.out.println("For SSH/SFTP volumes, use the format host:path OR user@host:path - path can be an empty string which will be the home directory of the user");
+ System.out.println();
+ System.out.println("Options:");
+ System.out.println("--from local directory or SSH volume (user@host:path)");
+ System.out.println("--to local directory or SSH volume (user@host:path)");
+ System.out.println("--mode nest or merge");
+ System.out.println("--no-verbose disable verbose output");
+ System.out.println("--no-progress disable progress output");
+ System.out.println("--parents enable creating parent directories on target if they don't exist");
+ System.out.println("--force enable updating target file/dir type mismatches if they exist");
+ System.out.println("--delete delete dirs/files on target if they don't exist on source");
+ System.out.println();
+ System.out.println("Examples:");
+ System.out.println("blaze examples/jsync.java --from /tmp/from --to /tmp/to");
+ System.out.println("blaze examples/jsync.java --from user@host:/tmp/from --to /tmp/to");
+ }
+
+ public VirtualVolume detectVolume(String volume) {
+ int colonPos = volume.indexOf(":");
+
+ if (colonPos >= 0) {
+ // this may be SSH, although it could also be a windows path
+ String host = volume.substring(0, colonPos);
+ if (host.length() > 2) {
+ // assume this is an SSH volume
+ final String pathStr = volume.substring(colonPos+1);
+ final String path = pathStr.isEmpty() ? "." : pathStr;
+ return sftpVolume(host, path);
+ }
+ }
+
+ // otherwise, assume it's local
+ return localVolume(Paths.get(volume));
+ }
+
+}
diff --git a/examples/undertow.java b/examples/undertow.java
index 27ffa203..8ab01f0e 100644
--- a/examples/undertow.java
+++ b/examples/undertow.java
@@ -1,9 +1,6 @@
import com.fizzed.blaze.Config;
import com.fizzed.blaze.Contexts;
import io.undertow.Undertow;
-import io.undertow.server.HttpHandler;
-import io.undertow.server.HttpServerExchange;
-import io.undertow.util.Headers;
import io.undertow.server.handlers.resource.PathResourceManager;
import static io.undertow.Handlers.resource;
import java.nio.file.Path;
diff --git a/pom.xml b/pom.xml
index 976e201e..3eaed817 100644
--- a/pom.xml
+++ b/pom.xml
@@ -238,7 +238,7 @@
com.fizzed
jne
- 4.10.0
+ 4.11.0