Adding 'shell' subcommand for 'acx' to enable multiple commands. Needs to run from a pipe as well, limiting shell capabilities a bit (?).
This commit is contained in:
parent
47206f0fd8
commit
25ddc7f66a
|
@ -19,36 +19,17 @@
|
||||||
*/
|
*/
|
||||||
package io.github.applecommander.acx;
|
package io.github.applecommander.acx;
|
||||||
|
|
||||||
import java.util.logging.Handler;
|
import io.github.applecommander.acx.command.*;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.LogManager;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import io.github.applecommander.acx.command.CompareCommand;
|
|
||||||
import io.github.applecommander.acx.command.ConvertCommand;
|
|
||||||
import io.github.applecommander.acx.command.CopyFileCommand;
|
|
||||||
import io.github.applecommander.acx.command.CreateDiskCommand;
|
|
||||||
import io.github.applecommander.acx.command.DeleteCommand;
|
|
||||||
import io.github.applecommander.acx.command.DiskMapCommand;
|
|
||||||
import io.github.applecommander.acx.command.DumpCommand;
|
|
||||||
import io.github.applecommander.acx.command.ExportCommand;
|
|
||||||
import io.github.applecommander.acx.command.FindDuplicateFilesCommand;
|
|
||||||
import io.github.applecommander.acx.command.ImportCommand;
|
|
||||||
import io.github.applecommander.acx.command.InfoCommand;
|
|
||||||
import io.github.applecommander.acx.command.ListCommand;
|
|
||||||
import io.github.applecommander.acx.command.LockCommand;
|
|
||||||
import io.github.applecommander.acx.command.MkdirCommand;
|
|
||||||
import io.github.applecommander.acx.command.ReadCommand;
|
|
||||||
import io.github.applecommander.acx.command.RenameDiskCommand;
|
|
||||||
import io.github.applecommander.acx.command.RenameFileCommand;
|
|
||||||
import io.github.applecommander.acx.command.RmdirCommand;
|
|
||||||
import io.github.applecommander.acx.command.UnlockCommand;
|
|
||||||
import io.github.applecommander.acx.command.WriteCommand;
|
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import picocli.CommandLine.Command;
|
import picocli.CommandLine.Command;
|
||||||
import picocli.CommandLine.HelpCommand;
|
import picocli.CommandLine.HelpCommand;
|
||||||
import picocli.CommandLine.Option;
|
import picocli.CommandLine.Option;
|
||||||
|
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.LogManager;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primary entry point into the 'acx' utility.
|
* Primary entry point into the 'acx' utility.
|
||||||
*/
|
*/
|
||||||
|
@ -77,6 +58,7 @@ import picocli.CommandLine.Option;
|
||||||
RenameFileCommand.class,
|
RenameFileCommand.class,
|
||||||
RenameDiskCommand.class,
|
RenameDiskCommand.class,
|
||||||
RmdirCommand.class,
|
RmdirCommand.class,
|
||||||
|
ShellCommand.class,
|
||||||
UnlockCommand.class,
|
UnlockCommand.class,
|
||||||
WriteCommand.class
|
WriteCommand.class
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* AppleCommander - An Apple ][ image utility.
|
||||||
|
* Copyright (C) 2019-2023 by Robert Greene and others
|
||||||
|
* robgreene at users.sourceforge.net
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package io.github.applecommander.acx.command;
|
||||||
|
|
||||||
|
import io.github.applecommander.acx.PrintExceptionMessageHandler;
|
||||||
|
import picocli.CommandLine;
|
||||||
|
import picocli.CommandLine.Command;
|
||||||
|
import picocli.CommandLine.Parameters;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Command(name = "shell",
|
||||||
|
descriptionHeading = "%n",
|
||||||
|
commandListHeading = "%nCommands:%n",
|
||||||
|
optionListHeading = "%nOptions:%n",
|
||||||
|
description = "Enter 'acx' shell mode to support multiple commands.",
|
||||||
|
subcommands = {
|
||||||
|
CompareCommand.class,
|
||||||
|
ConvertCommand.class,
|
||||||
|
CopyFileCommand.class,
|
||||||
|
CreateDiskCommand.class,
|
||||||
|
DeleteCommand.class,
|
||||||
|
DiskMapCommand.class,
|
||||||
|
DumpCommand.class,
|
||||||
|
ExportCommand.class,
|
||||||
|
FindDuplicateFilesCommand.class,
|
||||||
|
CommandLine.HelpCommand.class,
|
||||||
|
ImportCommand.class,
|
||||||
|
InfoCommand.class,
|
||||||
|
ListCommand.class,
|
||||||
|
LockCommand.class,
|
||||||
|
MkdirCommand.class,
|
||||||
|
ReadCommand.class,
|
||||||
|
RenameFileCommand.class,
|
||||||
|
RenameDiskCommand.class,
|
||||||
|
RmdirCommand.class,
|
||||||
|
UnlockCommand.class,
|
||||||
|
WriteCommand.class
|
||||||
|
})
|
||||||
|
public class ShellCommand implements Callable<Integer> {
|
||||||
|
private static final String PROMPT = "ACX> ";
|
||||||
|
|
||||||
|
private boolean exit = false;
|
||||||
|
@Command(name = "exit", aliases = { "quit" }, description = "Exit shell environment")
|
||||||
|
public void exitShell() {
|
||||||
|
exit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String defaultDiskName = null;
|
||||||
|
@Command(name = "default", description = "Display or set the default disk")
|
||||||
|
public void defaultDisk(@Parameters(description = "Disk to be set as default", arity = "0..1", defaultValue = "") String diskName) {
|
||||||
|
if (diskName == null || diskName.isEmpty()) {
|
||||||
|
if (defaultDiskName == null) {
|
||||||
|
System.out.println("No default disk has been set.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.printf("The default disk is '%s'.\n", defaultDiskName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we don't know the commands being used, so can't really test for existence...
|
||||||
|
defaultDiskName = diskName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws IOException {
|
||||||
|
final boolean isTTY = (System.console() != null);
|
||||||
|
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
|
||||||
|
while (!exit) {
|
||||||
|
System.out.print(PROMPT);
|
||||||
|
String line = reader.readLine();
|
||||||
|
if (line == null) break;
|
||||||
|
if (!isTTY) {
|
||||||
|
System.out.println(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandLine cmd = new CommandLine(new ShellCommand());
|
||||||
|
cmd.setExecutionExceptionHandler(new PrintExceptionMessageHandler());
|
||||||
|
cmd.setCaseInsensitiveEnumValuesAllowed(true);
|
||||||
|
|
||||||
|
List<String> args = getArgs(line);
|
||||||
|
if (defaultDiskName != null) {
|
||||||
|
System.setProperty("ACX_DISK_NAME", defaultDiskName);
|
||||||
|
}
|
||||||
|
cmd.execute(args.toArray(new String[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> getArgs(String line) {
|
||||||
|
// See https://stackoverflow.com/questions/7804335/split-string-on-spaces-in-java-except-if-between-quotes-i-e-treat-hello-wor
|
||||||
|
final Pattern splitter = Pattern.compile("([^\"]\\S*|\".+?\")\\s*");
|
||||||
|
|
||||||
|
Matcher m = splitter.matcher(line);
|
||||||
|
List<String> args = new ArrayList<>();
|
||||||
|
while (m.find()) {
|
||||||
|
String s = m.group(1);
|
||||||
|
if (s.startsWith("\"") && s.endsWith("\"")) {
|
||||||
|
s = s.substring(1, s.length()-1);
|
||||||
|
}
|
||||||
|
args.add(s);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue