use of org.jline.builtins.Options in project felix by apache.
the class Posix method ls.
protected void ls(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "ls - list files", "Usage: ls [OPTIONS] [PATTERNS...]", " -? --help show help", " -1 list one entry per line", " -C multi-column output", " --color=WHEN colorize the output, may be `always', `never' or `auto'", " -a list entries starting with .", " -F append file type indicators", " -m comma separated", " -l long listing", " -S sort by size", " -f output is not sorted", " -r reverse sort order", " -t sort by modification time", " -x sort horizontally", " -L list referenced file for links", " -h print sizes in human readable form" };
Options opt = parseOptions(session, usage, argv);
String color = opt.isSet("color") ? opt.get("color") : "auto";
boolean colored;
switch(color) {
case "always":
case "yes":
case "force":
colored = true;
break;
case "never":
case "no":
case "none":
colored = false;
break;
case "auto":
case "tty":
case "if-tty":
colored = process.isTty(1);
break;
default:
throw new IllegalArgumentException("invalid argument ‘" + color + "’ for ‘--color’");
}
Map<String, String> colors = colored ? getLsColorMap(session) : Collections.emptyMap();
class PathEntry implements Comparable<PathEntry> {
final Path abs;
final Path path;
final Map<String, Object> attributes;
public PathEntry(Path abs, Path root) {
this.abs = abs;
this.path = abs.startsWith(root) ? root.relativize(abs) : abs;
this.attributes = readAttributes(abs);
}
@Override
public int compareTo(PathEntry o) {
int c = doCompare(o);
return opt.isSet("r") ? -c : c;
}
private int doCompare(PathEntry o) {
if (opt.isSet("f")) {
return -1;
}
if (opt.isSet("S")) {
long s0 = attributes.get("size") != null ? ((Number) attributes.get("size")).longValue() : 0L;
long s1 = o.attributes.get("size") != null ? ((Number) o.attributes.get("size")).longValue() : 0L;
return s0 > s1 ? -1 : s0 < s1 ? 1 : path.toString().compareTo(o.path.toString());
}
if (opt.isSet("t")) {
long t0 = attributes.get("lastModifiedTime") != null ? ((FileTime) attributes.get("lastModifiedTime")).toMillis() : 0L;
long t1 = o.attributes.get("lastModifiedTime") != null ? ((FileTime) o.attributes.get("lastModifiedTime")).toMillis() : 0L;
return t0 > t1 ? -1 : t0 < t1 ? 1 : path.toString().compareTo(o.path.toString());
}
return path.toString().compareTo(o.path.toString());
}
boolean isNotDirectory() {
return is("isRegularFile") || is("isSymbolicLink") || is("isOther");
}
boolean isDirectory() {
return is("isDirectory");
}
private boolean is(String attr) {
Object d = attributes.get(attr);
return d instanceof Boolean && (Boolean) d;
}
String display() {
String type;
String suffix;
String link = "";
if (is("isSymbolicLink")) {
type = "sl";
suffix = "@";
try {
Path l = Files.readSymbolicLink(abs);
link = " -> " + l.toString();
} catch (IOException e) {
// ignore
}
} else if (is("isDirectory")) {
type = "dr";
suffix = "/";
} else if (is("isExecutable")) {
type = "ex";
suffix = "*";
} else if (is("isOther")) {
type = "ot";
suffix = "";
} else {
type = "";
suffix = "";
}
String col = colors.get(type);
boolean addSuffix = opt.isSet("F");
if (col != null && !col.isEmpty()) {
return "\033[" + col + "m" + path.toString() + "\033[m" + (addSuffix ? suffix : "") + link;
} else {
return path.toString() + (addSuffix ? suffix : "") + link;
}
}
String longDisplay() {
String username;
if (attributes.containsKey("owner")) {
username = Objects.toString(attributes.get("owner"), null);
} else {
username = "owner";
}
if (username.length() > 8) {
username = username.substring(0, 8);
} else {
for (int i = username.length(); i < 8; i++) {
username = username + " ";
}
}
String group;
if (attributes.containsKey("group")) {
group = Objects.toString(attributes.get("group"), null);
} else {
group = "group";
}
if (group.length() > 8) {
group = group.substring(0, 8);
} else {
for (int i = group.length(); i < 8; i++) {
group = group + " ";
}
}
Number length = (Number) attributes.get("size");
if (length == null) {
length = 0L;
}
String lengthString;
if (opt.isSet("h")) {
double l = length.longValue();
String unit = "B";
if (l >= 1000) {
l /= 1024;
unit = "K";
if (l >= 1000) {
l /= 1024;
unit = "M";
if (l >= 1000) {
l /= 1024;
unit = "T";
}
}
}
if (l < 10 && length.longValue() > 1000) {
lengthString = String.format("%.1f", l) + unit;
} else {
lengthString = String.format("%3.0f", l) + unit;
}
} else {
lengthString = String.format("%1$8s", length);
}
@SuppressWarnings("unchecked") Set<PosixFilePermission> perms = (Set<PosixFilePermission>) attributes.get("permissions");
if (perms == null) {
perms = EnumSet.noneOf(PosixFilePermission.class);
}
// TODO: all fields should be padded to align
return (is("isDirectory") ? "d" : (is("isSymbolicLink") ? "l" : (is("isOther") ? "o" : "-"))) + PosixFilePermissions.toString(perms) + " " + String.format("%3s", (attributes.containsKey("nlink") ? attributes.get("nlink").toString() : "1")) + " " + username + " " + group + " " + lengthString + " " + toString((FileTime) attributes.get("lastModifiedTime")) + " " + display();
}
protected String toString(FileTime time) {
long millis = (time != null) ? time.toMillis() : -1L;
if (millis < 0L) {
return "------------";
}
ZonedDateTime dt = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault());
// Less than six months
if (System.currentTimeMillis() - millis < 183L * 24L * 60L * 60L * 1000L) {
return DateTimeFormatter.ofPattern("MMM ppd HH:mm").format(dt);
} else // Older than six months
{
return DateTimeFormatter.ofPattern("MMM ppd yyyy").format(dt);
}
}
protected Map<String, Object> readAttributes(Path path) {
Map<String, Object> attrs = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (String view : path.getFileSystem().supportedFileAttributeViews()) {
try {
Map<String, Object> ta = Files.readAttributes(path, view + ":*", getLinkOptions(opt.isSet("L")));
ta.entrySet().forEach(e -> attrs.putIfAbsent(e.getKey(), e.getValue()));
} catch (IOException e) {
// Ignore
}
}
attrs.computeIfAbsent("isExecutable", s -> Files.isExecutable(path));
attrs.computeIfAbsent("permissions", s -> getPermissionsFromFile(path.toFile()));
return attrs;
}
}
Path currentDir = session.currentDir();
// Listing
List<Path> expanded = new ArrayList<>();
if (opt.args().isEmpty()) {
expanded.add(currentDir);
} else {
opt.args().forEach(s -> expanded.add(currentDir.resolve(s)));
}
boolean listAll = opt.isSet("a");
Predicate<Path> filter = p -> listAll || !p.getFileName().toString().startsWith(".");
List<PathEntry> all = expanded.stream().filter(filter).map(p -> new PathEntry(p, currentDir)).sorted().collect(Collectors.toList());
// Print files first
List<PathEntry> files = all.stream().filter(PathEntry::isNotDirectory).collect(Collectors.toList());
PrintStream out = process.out();
Consumer<Stream<PathEntry>> display = s -> {
boolean optLine = opt.isSet("1");
boolean optComma = opt.isSet("m");
boolean optLong = opt.isSet("l");
boolean optCol = opt.isSet("C");
if (!optLine && !optComma && !optLong && !optCol) {
if (process.isTty(1)) {
optCol = true;
} else {
optLine = true;
}
}
// One entry per line
if (optLine) {
s.map(PathEntry::display).forEach(out::println);
} else // Comma separated list
if (optComma) {
out.println(s.map(PathEntry::display).collect(Collectors.joining(", ")));
} else // Long listing
if (optLong) {
s.map(PathEntry::longDisplay).forEach(out::println);
} else // Column listing
if (optCol) {
toColumn(session, process, out, s.map(PathEntry::display), opt.isSet("x"));
}
};
boolean space = false;
if (!files.isEmpty()) {
display.accept(files.stream());
space = true;
}
// Print directories
List<PathEntry> directories = all.stream().filter(PathEntry::isDirectory).collect(Collectors.toList());
for (PathEntry entry : directories) {
if (space) {
out.println();
}
space = true;
Path path = currentDir.resolve(entry.path);
if (expanded.size() > 1) {
out.println(currentDir.relativize(path).toString() + ":");
}
display.accept(Stream.concat(Arrays.asList(".", "..").stream().map(path::resolve), Files.list(path)).filter(filter).map(p -> new PathEntry(p, path)).sorted());
}
}
use of org.jline.builtins.Options in project felix by apache.
the class Posix method sleep.
protected void sleep(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "sleep - suspend execution for an interval of time", "Usage: sleep seconds", " -? --help show help" };
Options opt = parseOptions(session, usage, argv);
List<String> args = opt.args();
if (args.size() != 1) {
throw new IllegalArgumentException("usage: sleep seconds");
} else {
int s = Integer.parseInt(args.get(0));
Thread.sleep(s * 1000);
}
}
use of org.jline.builtins.Options in project felix by apache.
the class Posix method cd.
protected void cd(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "cd - get current directory", "Usage: cd [OPTIONS] DIRECTORY", " -? --help show help" };
Options opt = parseOptions(session, usage, argv);
if (opt.args().size() != 1) {
throw new IllegalArgumentException("usage: cd DIRECTORY");
}
Path cwd = session.currentDir();
cwd = cwd.resolve(opt.args().get(0)).toAbsolutePath();
if (!Files.exists(cwd)) {
throw new IOException("no such file or directory: " + opt.args().get(0));
} else if (!Files.isDirectory(cwd)) {
throw new IOException("not a directory: " + opt.args().get(0));
}
session.currentDir(cwd);
}
use of org.jline.builtins.Options in project felix by apache.
the class Posix method nano.
protected void nano(final CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "nano - edit files", "Usage: nano [FILES]", " -? --help Show help" };
Options opt = parseOptions(session, usage, argv);
Nano edit = new Nano(Shell.getTerminal(session), session.currentDir());
edit.open(opt.args());
edit.run();
}
use of org.jline.builtins.Options in project felix by apache.
the class Posix method cat.
protected void cat(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "cat - concatenate and print FILES", "Usage: cat [OPTIONS] [FILES]", " -? --help show help", " -n number the output lines, starting at 1" };
Options opt = parseOptions(session, usage, argv);
List<String> args = opt.args();
if (args.isEmpty()) {
args = Collections.singletonList("-");
}
Path cwd = session.currentDir();
for (String arg : args) {
InputStream is;
if ("-".equals(arg)) {
is = process.in();
} else {
is = cwd.toUri().resolve(arg).toURL().openStream();
}
cat(process, new BufferedReader(new InputStreamReader(is)), opt.isSet("n"));
}
}
Aggregations