</dependency>
<!-- Apache Commons -->
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.exec</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.cli</artifactId>
- </dependency>
<dependency>
<groupId>org.argeo.tp.apache.commons</groupId>
<artifactId>org.apache.commons.vfs</artifactId>
package org.argeo.cli.jcr;
-import org.argeo.cli.CommandsCli;
+import org.argeo.cms.cli.CommandsCli;
/** File utilities. */
public class JcrCommands extends CommandsCli {
import org.apache.commons.cli.Options;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.cli.CommandArgsException;
-import org.argeo.cli.CommandRuntimeException;
-import org.argeo.cli.DescribedCommand;
+import org.argeo.cms.cli.CommandArgsException;
+import org.argeo.cms.cli.CommandRuntimeException;
+import org.argeo.cms.cli.DescribedCommand;
import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
import org.argeo.jcr.JcrUtils;
import org.argeo.sync.SyncResult;
-<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/maven-v4_0_0.xsd">
+<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.argeo.slc</groupId>
<version>2.3-SNAPSHOT</version>
</dependency>
+ <!-- Commons -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.api</artifactId>
+ <artifactId>org.argeo.cms</artifactId>
<version>${version.argeo-commons}</version>
</dependency>
+
</dependencies>
</project>
\ No newline at end of file
+++ /dev/null
-package org.argeo.cli;
-
-public class CommandArgsException extends IllegalArgumentException {
- private static final long serialVersionUID = -7271050747105253935L;
- private String commandName;
- private volatile CommandsCli commandsCli;
-
- public CommandArgsException(Exception cause) {
- super(cause.getMessage(), cause);
- }
-
- public CommandArgsException(String message) {
- super(message);
- }
-
- public String getCommandName() {
- return commandName;
- }
-
- public void setCommandName(String commandName) {
- this.commandName = commandName;
- }
-
- public CommandsCli getCommandsCli() {
- return commandsCli;
- }
-
- public void setCommandsCli(CommandsCli commandsCli) {
- this.commandsCli = commandsCli;
- }
-
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.util.List;
-
-/** {@link RuntimeException} referring during a command run. */
-public class CommandRuntimeException extends RuntimeException {
- private static final long serialVersionUID = 5595999301269377128L;
-
- private final DescribedCommand<?> command;
- private final List<String> arguments;
-
- public CommandRuntimeException(Throwable e, DescribedCommand<?> command, List<String> arguments) {
- this(null, e, command, arguments);
- }
-
- public CommandRuntimeException(String message, DescribedCommand<?> command, List<String> arguments) {
- this(message, null, command, arguments);
- }
-
- public CommandRuntimeException(String message, Throwable e, DescribedCommand<?> command, List<String> arguments) {
- super(message == null ? "(" + command.getClass().getName() + " " + arguments.toString() + ")"
- : message + " (" + command.getClass().getName() + " " + arguments.toString() + ")", e);
- this.command = command;
- this.arguments = arguments;
- }
-
- public DescribedCommand<?> getCommand() {
- return command;
- }
-
- public List<String> getArguments() {
- return arguments;
- }
-
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.function.Function;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Base class for a CLI managing sub commands. */
-public abstract class CommandsCli implements DescribedCommand<Object> {
- public final static String HELP = "help";
-
- private final String commandName;
- private Map<String, Function<List<String>, ?>> commands = new TreeMap<>();
-
- protected final Options options = new Options();
-
- public CommandsCli(String commandName) {
- this.commandName = commandName;
- }
-
- @Override
- public Object apply(List<String> args) {
- String cmd = null;
- List<String> newArgs = new ArrayList<>();
- try {
- CommandLineParser clParser = new DefaultParser();
- CommandLine commonCl = clParser.parse(getOptions(), args.toArray(new String[args.size()]), true);
- List<String> leftOvers = commonCl.getArgList();
- for (String arg : leftOvers) {
- if (!arg.startsWith("-") && cmd == null) {
- cmd = arg;
- } else {
- newArgs.add(arg);
- }
- }
- } catch (ParseException e) {
- CommandArgsException cae = new CommandArgsException(e);
- throw cae;
- }
-
- Function<List<String>, ?> function = cmd != null ? getCommand(cmd) : getDefaultCommand();
- if (function == null)
- throw new IllegalArgumentException("Uknown command " + cmd);
- try {
- return function.apply(newArgs).toString();
- } catch (CommandArgsException e) {
- if (e.getCommandName() == null) {
- e.setCommandName(cmd);
- e.setCommandsCli(this);
- }
- throw e;
- } catch (IllegalArgumentException e) {
- CommandArgsException cae = new CommandArgsException(e);
- cae.setCommandName(cmd);
- throw cae;
- }
- }
-
- @Override
- public Options getOptions() {
- return options;
- }
-
- protected void addCommand(String cmd, Function<List<String>, ?> function) {
- commands.put(cmd, function);
-
- }
-
- @Override
- public String getUsage() {
- return "[command]";
- }
-
- protected void addCommandsCli(CommandsCli commandsCli) {
- addCommand(commandsCli.getCommandName(), commandsCli);
- commandsCli.addCommand(HELP, new HelpCommand(this, commandsCli));
- }
-
- public String getCommandName() {
- return commandName;
- }
-
- public Set<String> getSubCommands() {
- return commands.keySet();
- }
-
- public Function<List<String>, ?> getCommand(String command) {
- return commands.get(command);
- }
-
- public HelpCommand getHelpCommand() {
- return (HelpCommand) getCommand(HELP);
- }
-
- public Function<List<String>, String> getDefaultCommand() {
- return getHelpCommand();
- }
-
- /** In order to implement quickly a main method. */
- public static void mainImpl(CommandsCli cli, String[] args) {
- try {
- cli.addCommand(CommandsCli.HELP, new HelpCommand(null, cli));
- Object output = cli.apply(Arrays.asList(args));
- System.out.println(output);
- System.exit(0);
- } catch (CommandArgsException e) {
- System.err.println("Wrong arguments " + Arrays.toString(args) + ": " + e.getMessage());
- if (e.getCommandName() != null) {
- StringWriter out = new StringWriter();
- HelpCommand.printHelp(e.getCommandsCli(), e.getCommandName(), out);
- System.err.println(out.toString());
- } else {
- e.printStackTrace();
- }
- System.exit(1);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Function;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** A command that can be described. */
-public interface DescribedCommand<T> extends Function<List<String>, T> {
- default Options getOptions() {
- return new Options();
- }
-
- String getDescription();
-
- default String getUsage() {
- return null;
- }
-
- default String getExamples() {
- return null;
- }
-
- default CommandLine toCommandLine(List<String> args) {
- try {
- DefaultParser parser = new DefaultParser();
- return parser.parse(getOptions(), args.toArray(new String[args.size()]));
- } catch (ParseException e) {
- throw new CommandArgsException(e);
- }
- }
-
- /** In order to implement quickly a main method. */
- public static void mainImpl(DescribedCommand<?> command, String[] args) {
- try {
- Object output = command.apply(Arrays.asList(args));
- System.out.println(output);
- System.exit(0);
- } catch (IllegalArgumentException e) {
- StringWriter out = new StringWriter();
- HelpCommand.printHelp(command, out);
- System.err.println(out.toString());
- System.exit(1);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.function.Function;
-
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Options;
-
-/** A special command that can describe {@link DescribedCommand}. */
-public class HelpCommand implements DescribedCommand<String> {
- private CommandsCli commandsCli;
- private CommandsCli parentCommandsCli;
-
- // Help formatting
- private static int helpWidth = 80;
- private static int helpLeftPad = 4;
- private static int helpDescPad = 20;
-
- public HelpCommand(CommandsCli parentCommandsCli, CommandsCli commandsCli) {
- super();
- this.parentCommandsCli = parentCommandsCli;
- this.commandsCli = commandsCli;
- }
-
- @Override
- public String apply(List<String> args) {
- StringWriter out = new StringWriter();
-
- if (args.size() == 0) {// overview
- printHelp(commandsCli, out);
- } else {
- String cmd = args.get(0);
- Function<List<String>, ?> function = commandsCli.getCommand(cmd);
- if (function == null)
- return "Command " + cmd + " not found.";
- Options options;
- String examples;
- DescribedCommand<?> command = null;
- if (function instanceof DescribedCommand) {
- command = (DescribedCommand<?>) function;
- options = command.getOptions();
- examples = command.getExamples();
- } else {
- options = new Options();
- examples = null;
- }
- String description = getShortDescription(function);
- String commandCall = getCommandUsage(cmd, command);
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, commandCall, description, options, helpLeftPad,
- helpDescPad, examples, false);
- }
- return out.toString();
- }
-
- private static String getShortDescription(Function<List<String>, ?> function) {
- if (function instanceof DescribedCommand) {
- return ((DescribedCommand<?>) function).getDescription();
- } else {
- return function.toString();
- }
- }
-
- public String getCommandUsage(String cmd, DescribedCommand<?> command) {
- String commandCall = getCommandCall(commandsCli) + " " + cmd;
- assert command != null;
- if (command != null && command.getUsage() != null) {
- commandCall = commandCall + " " + command.getUsage();
- }
- return commandCall;
- }
-
- @Override
- public String getDescription() {
- return "Shows this help or describes a command";
- }
-
- @Override
- public String getUsage() {
- return "[command]";
- }
-
- public CommandsCli getParentCommandsCli() {
- return parentCommandsCli;
- }
-
- protected String getCommandCall(CommandsCli commandsCli) {
- HelpCommand hc = commandsCli.getHelpCommand();
- if (hc.getParentCommandsCli() != null) {
- return getCommandCall(hc.getParentCommandsCli()) + " " + commandsCli.getCommandName();
- } else {
- return commandsCli.getCommandName();
- }
- }
-
- public static void printHelp(DescribedCommand<?> command, StringWriter out) {
- String usage = "java " + command.getClass().getName()
- + (command.getUsage() != null ? " " + command.getUsage() : "");
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
- helpLeftPad, helpDescPad, command.getExamples(), false);
-
- }
-
- public static void printHelp(CommandsCli commandsCli, String commandName, StringWriter out) {
- DescribedCommand<?> command = (DescribedCommand<?>) commandsCli.getCommand(commandName);
- String usage = commandsCli.getHelpCommand().getCommandUsage(commandName, command);
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
- helpLeftPad, helpDescPad, command.getExamples(), false);
-
- }
-
- public static void printHelp(CommandsCli commandsCli, StringWriter out) {
- out.append(commandsCli.getDescription()).append('\n');
- String leftPad = spaces(helpLeftPad);
- for (String cmd : commandsCli.getSubCommands()) {
- Function<List<String>, ?> function = commandsCli.getCommand(cmd);
- assert function != null;
- out.append(leftPad);
- out.append(cmd);
- // TODO deal with long commands
- out.append(spaces(helpDescPad - cmd.length()));
- out.append(getShortDescription(function));
- out.append('\n');
- }
- }
-
- private static String spaces(int count) {
- // Java 11
- // return " ".repeat(count);
- if (count <= 0)
- return "";
- else {
- StringBuilder sb = new StringBuilder(count);
- for (int i = 0; i < count; i++)
- sb.append(' ');
- return sb.toString();
- }
- }
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.argeo.cli.CommandArgsException;
-import org.argeo.cli.DescribedCommand;
-import org.argeo.sync.SyncResult;
-
-public class FileSync implements DescribedCommand<SyncResult<Path>> {
- final static Option deleteOption = Option.builder().longOpt("delete").desc("delete from target").build();
- final static Option recursiveOption = Option.builder("r").longOpt("recursive").desc("recurse into directories")
- .build();
- final static Option progressOption = Option.builder().longOpt("progress").hasArg(false).desc("show progress")
- .build();
-
- @Override
- public SyncResult<Path> apply(List<String> t) {
- try {
- CommandLine line = toCommandLine(t);
- List<String> remaining = line.getArgList();
- if (remaining.size() == 0) {
- throw new CommandArgsException("There must be at least one argument");
- }
- URI sourceUri = new URI(remaining.get(0));
- URI targetUri;
- if (remaining.size() == 1) {
- targetUri = Paths.get(System.getProperty("user.dir")).toUri();
- } else {
- targetUri = new URI(remaining.get(1));
- }
- boolean delete = line.hasOption(deleteOption.getLongOpt());
- boolean recursive = line.hasOption(recursiveOption.getLongOpt());
- PathSync pathSync = new PathSync(sourceUri, targetUri, delete, recursive);
- return pathSync.call();
- } catch (URISyntaxException e) {
- throw new CommandArgsException(e);
- }
- }
-
- @Override
- public Options getOptions() {
- Options options = new Options();
- options.addOption(recursiveOption);
- options.addOption(deleteOption);
- options.addOption(progressOption);
- return options;
- }
-
- @Override
- public String getUsage() {
- return "[source URI] [target URI]";
- }
-
- public static void main(String[] args) {
- DescribedCommand.mainImpl(new FileSync(), args);
-// Options options = new Options();
-// options.addOption("r", "recursive", false, "recurse into directories");
-// options.addOption(Option.builder().longOpt("progress").hasArg(false).desc("show progress").build());
-//
-// CommandLineParser parser = new DefaultParser();
-// try {
-// CommandLine line = parser.parse(options, args);
-// List<String> remaining = line.getArgList();
-// if (remaining.size() == 0) {
-// System.err.println("There must be at least one argument");
-// printHelp(options);
-// System.exit(1);
-// }
-// URI sourceUri = new URI(remaining.get(0));
-// URI targetUri;
-// if (remaining.size() == 1) {
-// targetUri = Paths.get(System.getProperty("user.dir")).toUri();
-// } else {
-// targetUri = new URI(remaining.get(1));
-// }
-// PathSync pathSync = new PathSync(sourceUri, targetUri);
-// pathSync.run();
-// } catch (Exception exp) {
-// exp.printStackTrace();
-// printHelp(options);
-// System.exit(1);
-// }
- }
-
-// public static void printHelp(Options options) {
-// HelpFormatter formatter = new HelpFormatter();
-// formatter.printHelp("sync SRC [DEST]", options, true);
-// }
-
- @Override
- public String getDescription() {
- return "Synchronises files";
- }
-
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import org.argeo.cli.CommandsCli;
-
-/** File utilities. */
-public class FsCommands extends CommandsCli {
-
- public FsCommands(String commandName) {
- super(commandName);
- addCommand("sync", new FileSync());
- }
-
- @Override
- public String getDescription() {
- return "Utilities around files and file systems";
- }
-
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import java.net.URI;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.spi.FileSystemProvider;
-import java.util.concurrent.Callable;
-
-import org.argeo.sync.SyncResult;
-
-/** Synchronises two paths. */
-public class PathSync implements Callable<SyncResult<Path>> {
- private final URI sourceUri, targetUri;
- private final boolean delete;
- private final boolean recursive;
-
- public PathSync(URI sourceUri, URI targetUri) {
- this(sourceUri, targetUri, false, false);
- }
-
- public PathSync(URI sourceUri, URI targetUri, boolean delete, boolean recursive) {
- this.sourceUri = sourceUri;
- this.targetUri = targetUri;
- this.delete = delete;
- this.recursive = recursive;
- }
-
- @Override
- public SyncResult<Path> call() {
- try {
- Path sourceBasePath = createPath(sourceUri);
- Path targetBasePath = createPath(targetUri);
- SyncFileVisitor syncFileVisitor = new SyncFileVisitor(sourceBasePath, targetBasePath, delete, recursive);
- Files.walkFileTree(sourceBasePath, syncFileVisitor);
- return syncFileVisitor.getSyncResult();
- } catch (Exception e) {
- throw new IllegalStateException("Cannot sync " + sourceUri + " to " + targetUri, e);
- }
- }
-
- private Path createPath(URI uri) {
- Path path;
- if (uri.getScheme() == null) {
- path = Paths.get(uri.getPath());
- } else if (uri.getScheme().equals("file")) {
- FileSystemProvider fsProvider = FileSystems.getDefault().provider();
- path = fsProvider.getPath(uri);
- } else if (uri.getScheme().equals("davex")) {
- throw new UnsupportedOperationException();
-// FileSystemProvider fsProvider = new DavexFsProvider();
-// path = fsProvider.getPath(uri);
-// } else if (uri.getScheme().equals("sftp")) {
-// Sftp sftp = new Sftp(uri);
-// path = sftp.getBasePath();
- } else
- throw new IllegalArgumentException("URI scheme not supported for " + uri);
- return path;
- }
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import java.nio.file.Path;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.fs.BasicSyncFileVisitor;
-
-/** Synchronises two directory structures. */
-public class SyncFileVisitor extends BasicSyncFileVisitor {
- private final static CmsLog log = CmsLog.getLog(SyncFileVisitor.class);
-
- public SyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete, boolean recursive) {
- super(sourceBasePath, targetBasePath, delete, recursive);
- }
-
- @Override
- protected void error(Object obj, Throwable e) {
- log.error(obj, e);
- }
-
- @Override
- protected boolean isTraceEnabled() {
- return log.isTraceEnabled();
- }
-
- @Override
- protected void trace(Object obj) {
- log.trace(obj);
- }
-}
+++ /dev/null
-/** File system CLI commands. */
-package org.argeo.cli.fs;
\ No newline at end of file
+++ /dev/null
-/** Command line API. */
-package org.argeo.cli;
\ No newline at end of file
+++ /dev/null
-package org.argeo.cli.posix;
-
-import java.util.List;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.argeo.cli.DescribedCommand;
-
-public class Echo implements DescribedCommand<String> {
-
- @Override
- public Options getOptions() {
- Options options = new Options();
- options.addOption(Option.builder("n").desc("do not output the trailing newline").build());
- return options;
- }
-
- @Override
- public String getDescription() {
- return "Display a line of text";
- }
-
- @Override
- public String getUsage() {
- return "[STRING]...";
- }
-
- @Override
- public String apply(List<String> args) {
- CommandLine cl = toCommandLine(args);
-
- StringBuffer sb = new StringBuffer();
- for (String s : cl.getArgList()) {
- sb.append(s).append(' ');
- }
-
- if (cl.hasOption('n')) {
- sb.deleteCharAt(sb.length() - 1);
- } else {
- sb.setCharAt(sb.length() - 1, '\n');
- }
- return sb.toString();
- }
-
-}
+++ /dev/null
-package org.argeo.cli.posix;
-
-import org.argeo.cli.CommandsCli;
-
-/** POSIX commands. */
-public class PosixCommands extends CommandsCli {
-
- public PosixCommands(String commandName) {
- super(commandName);
- addCommand("echo", new Echo());
- }
-
- @Override
- public String getDescription() {
- return "Reimplementation of some POSIX commands in plain Java";
- }
-
- public static void main(String[] args) {
- mainImpl(new PosixCommands("argeo-posix"), args);
- }
-}
+++ /dev/null
-/** Posix CLI commands. */
-package org.argeo.cli.posix;
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.cli;
+
+import org.apache.commons.cli.Option;
+import org.argeo.cms.cli.CommandsCli;
+import org.argeo.slc.cli.fs.FsCommands;
+import org.argeo.slc.cli.posix.PosixCommands;
+
+/** Argeo command line tools. */
+public class ArgeoCli extends CommandsCli {
+
+ public ArgeoCli(String commandName) {
+ super(commandName);
+ // Common options
+ options.addOption(Option.builder("v").hasArg().argName("verbose").desc("verbosity").build());
+ options.addOption(
+ Option.builder("D").hasArgs().argName("property=value").desc("use value for given property").build());
+
+ addCommandsCli(new PosixCommands("posix"));
+ addCommandsCli(new FsCommands("fs"));
+// addCommandsCli(new JcrCommands("jcr"));
+ }
+
+ @Override
+ public String getDescription() {
+ return "Argeo command line utilities";
+ }
+
+ public static void main(String[] args) {
+ mainImpl(new ArgeoCli("argeo"), args);
+ }
+
+}
--- /dev/null
+package org.argeo.slc.cli.fs;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.argeo.cms.cli.CommandArgsException;
+import org.argeo.cms.cli.DescribedCommand;
+import org.argeo.sync.SyncResult;
+
+public class FileSync implements DescribedCommand<SyncResult<Path>> {
+ final static Option deleteOption = Option.builder().longOpt("delete").desc("delete from target").build();
+ final static Option recursiveOption = Option.builder("r").longOpt("recursive").desc("recurse into directories")
+ .build();
+ final static Option progressOption = Option.builder().longOpt("progress").hasArg(false).desc("show progress")
+ .build();
+
+ @Override
+ public SyncResult<Path> apply(List<String> t) {
+ try {
+ CommandLine line = toCommandLine(t);
+ List<String> remaining = line.getArgList();
+ if (remaining.size() == 0) {
+ throw new CommandArgsException("There must be at least one argument");
+ }
+ URI sourceUri = new URI(remaining.get(0));
+ URI targetUri;
+ if (remaining.size() == 1) {
+ targetUri = Paths.get(System.getProperty("user.dir")).toUri();
+ } else {
+ targetUri = new URI(remaining.get(1));
+ }
+ boolean delete = line.hasOption(deleteOption.getLongOpt());
+ boolean recursive = line.hasOption(recursiveOption.getLongOpt());
+ PathSync pathSync = new PathSync(sourceUri, targetUri, delete, recursive);
+ return pathSync.call();
+ } catch (URISyntaxException e) {
+ throw new CommandArgsException(e);
+ }
+ }
+
+ @Override
+ public Options getOptions() {
+ Options options = new Options();
+ options.addOption(recursiveOption);
+ options.addOption(deleteOption);
+ options.addOption(progressOption);
+ return options;
+ }
+
+ @Override
+ public String getUsage() {
+ return "[source URI] [target URI]";
+ }
+
+ public static void main(String[] args) {
+ DescribedCommand.mainImpl(new FileSync(), args);
+// Options options = new Options();
+// options.addOption("r", "recursive", false, "recurse into directories");
+// options.addOption(Option.builder().longOpt("progress").hasArg(false).desc("show progress").build());
+//
+// CommandLineParser parser = new DefaultParser();
+// try {
+// CommandLine line = parser.parse(options, args);
+// List<String> remaining = line.getArgList();
+// if (remaining.size() == 0) {
+// System.err.println("There must be at least one argument");
+// printHelp(options);
+// System.exit(1);
+// }
+// URI sourceUri = new URI(remaining.get(0));
+// URI targetUri;
+// if (remaining.size() == 1) {
+// targetUri = Paths.get(System.getProperty("user.dir")).toUri();
+// } else {
+// targetUri = new URI(remaining.get(1));
+// }
+// PathSync pathSync = new PathSync(sourceUri, targetUri);
+// pathSync.run();
+// } catch (Exception exp) {
+// exp.printStackTrace();
+// printHelp(options);
+// System.exit(1);
+// }
+ }
+
+// public static void printHelp(Options options) {
+// HelpFormatter formatter = new HelpFormatter();
+// formatter.printHelp("sync SRC [DEST]", options, true);
+// }
+
+ @Override
+ public String getDescription() {
+ return "Synchronises files";
+ }
+
+}
--- /dev/null
+package org.argeo.slc.cli.fs;
+
+import org.argeo.cms.cli.CommandsCli;
+
+/** File utilities. */
+public class FsCommands extends CommandsCli {
+
+ public FsCommands(String commandName) {
+ super(commandName);
+ addCommand("sync", new FileSync());
+ }
+
+ @Override
+ public String getDescription() {
+ return "Utilities around files and file systems";
+ }
+
+}
--- /dev/null
+package org.argeo.slc.cli.fs;
+
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.concurrent.Callable;
+
+import org.argeo.sync.SyncResult;
+
+/** Synchronises two paths. */
+public class PathSync implements Callable<SyncResult<Path>> {
+ private final URI sourceUri, targetUri;
+ private final boolean delete;
+ private final boolean recursive;
+
+ public PathSync(URI sourceUri, URI targetUri) {
+ this(sourceUri, targetUri, false, false);
+ }
+
+ public PathSync(URI sourceUri, URI targetUri, boolean delete, boolean recursive) {
+ this.sourceUri = sourceUri;
+ this.targetUri = targetUri;
+ this.delete = delete;
+ this.recursive = recursive;
+ }
+
+ @Override
+ public SyncResult<Path> call() {
+ try {
+ Path sourceBasePath = createPath(sourceUri);
+ Path targetBasePath = createPath(targetUri);
+ SyncFileVisitor syncFileVisitor = new SyncFileVisitor(sourceBasePath, targetBasePath, delete, recursive);
+ Files.walkFileTree(sourceBasePath, syncFileVisitor);
+ return syncFileVisitor.getSyncResult();
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot sync " + sourceUri + " to " + targetUri, e);
+ }
+ }
+
+ private Path createPath(URI uri) {
+ Path path;
+ if (uri.getScheme() == null) {
+ path = Paths.get(uri.getPath());
+ } else if (uri.getScheme().equals("file")) {
+ FileSystemProvider fsProvider = FileSystems.getDefault().provider();
+ path = fsProvider.getPath(uri);
+ } else if (uri.getScheme().equals("davex")) {
+ throw new UnsupportedOperationException();
+// FileSystemProvider fsProvider = new DavexFsProvider();
+// path = fsProvider.getPath(uri);
+// } else if (uri.getScheme().equals("sftp")) {
+// Sftp sftp = new Sftp(uri);
+// path = sftp.getBasePath();
+ } else
+ throw new IllegalArgumentException("URI scheme not supported for " + uri);
+ return path;
+ }
+}
--- /dev/null
+package org.argeo.slc.cli.fs;
+
+import java.nio.file.Path;
+
+import org.argeo.api.cms.CmsLog;
+import org.argeo.fs.BasicSyncFileVisitor;
+
+/** Synchronises two directory structures. */
+public class SyncFileVisitor extends BasicSyncFileVisitor {
+ private final static CmsLog log = CmsLog.getLog(SyncFileVisitor.class);
+
+ public SyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete, boolean recursive) {
+ super(sourceBasePath, targetBasePath, delete, recursive);
+ }
+
+ @Override
+ protected void error(Object obj, Throwable e) {
+ log.error(obj, e);
+ }
+
+ @Override
+ protected boolean isTraceEnabled() {
+ return log.isTraceEnabled();
+ }
+
+ @Override
+ protected void trace(Object obj) {
+ log.trace(obj);
+ }
+}
--- /dev/null
+/** File system CLI commands. */
+package org.argeo.slc.cli.fs;
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.cli.posix;
+
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.argeo.cms.cli.DescribedCommand;
+
+public class Echo implements DescribedCommand<String> {
+
+ @Override
+ public Options getOptions() {
+ Options options = new Options();
+ options.addOption(Option.builder("n").desc("do not output the trailing newline").build());
+ return options;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Display a line of text";
+ }
+
+ @Override
+ public String getUsage() {
+ return "[STRING]...";
+ }
+
+ @Override
+ public String apply(List<String> args) {
+ CommandLine cl = toCommandLine(args);
+
+ StringBuffer sb = new StringBuffer();
+ for (String s : cl.getArgList()) {
+ sb.append(s).append(' ');
+ }
+
+ if (cl.hasOption('n')) {
+ sb.deleteCharAt(sb.length() - 1);
+ } else {
+ sb.setCharAt(sb.length() - 1, '\n');
+ }
+ return sb.toString();
+ }
+
+}
--- /dev/null
+package org.argeo.slc.cli.posix;
+
+import org.argeo.cms.cli.CommandsCli;
+
+/** POSIX commands. */
+public class PosixCommands extends CommandsCli {
+
+ public PosixCommands(String commandName) {
+ super(commandName);
+ addCommand("echo", new Echo());
+ }
+
+ @Override
+ public String getDescription() {
+ return "Reimplementation of some POSIX commands in plain Java";
+ }
+
+ public static void main(String[] args) {
+ mainImpl(new PosixCommands("argeo-posix"), args);
+ }
+}
--- /dev/null
+/** Posix CLI commands. */
+package org.argeo.slc.cli.posix;
\ No newline at end of file
+++ /dev/null
-package org.argeo.slc.runtime;
-
-import org.apache.commons.cli.Option;
-import org.argeo.cli.CommandsCli;
-import org.argeo.cli.fs.FsCommands;
-import org.argeo.cli.posix.PosixCommands;
-
-/** Argeo command line tools. */
-public class ArgeoCli extends CommandsCli {
-
- public ArgeoCli(String commandName) {
- super(commandName);
- // Common options
- options.addOption(Option.builder("v").hasArg().argName("verbose").desc("verbosity").build());
- options.addOption(
- Option.builder("D").hasArgs().argName("property=value").desc("use value for given property").build());
-
- addCommandsCli(new PosixCommands("posix"));
- addCommandsCli(new FsCommands("fs"));
-// addCommandsCli(new JcrCommands("jcr"));
- }
-
- @Override
- public String getDescription() {
- return "Argeo command line utilities";
- }
-
- public static void main(String[] args) {
- mainImpl(new ArgeoCli("argeo"), args);
- }
-
-}