Skip to content

Commit

Permalink
Started implementing #1
Browse files Browse the repository at this point in the history
  • Loading branch information
sverhoeven committed Feb 6, 2017
1 parent 2b47683 commit 6f58070
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package nl.esciencecenter.xenon.cli;

import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import nl.esciencecenter.xenon.Xenon;
import nl.esciencecenter.xenon.XenonException;
import nl.esciencecenter.xenon.credentials.Credential;
import nl.esciencecenter.xenon.files.Files;

import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;

public class DownloadCommand extends CopyCommand {

@Override
public Subparser buildArgumentParser(Subparsers subparsers) {
Subparser subparser = subparsers.addParser("download")
.setDefault("subcommand", this)
.setDefault("operation", this)
.help("Download source file to local file")
.description("Download source file to local file");
subparser.addArgument("sourceLocation")
Expand Down
17 changes: 12 additions & 5 deletions src/main/java/nl/esciencecenter/xenon/cli/ListCommand.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package nl.esciencecenter.xenon.cli;

import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import nl.esciencecenter.xenon.Xenon;
import nl.esciencecenter.xenon.XenonException;
import nl.esciencecenter.xenon.credentials.Credential;
import nl.esciencecenter.xenon.files.*;
import nl.esciencecenter.xenon.files.DirectoryStream;
import nl.esciencecenter.xenon.files.FileAttributes;
import nl.esciencecenter.xenon.files.FileSystem;
import nl.esciencecenter.xenon.files.Files;
import nl.esciencecenter.xenon.files.Path;
import nl.esciencecenter.xenon.files.PathAttributesPair;
import nl.esciencecenter.xenon.files.RelativePath;

import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;

public class ListCommand extends XenonCommand {

Expand Down Expand Up @@ -38,7 +45,7 @@ private ListOutput listObjects(Files files, String scheme, String location, Stri

public Subparser buildArgumentParser(Subparsers subparsers) {
Subparser subparser = subparsers.addParser("list")
.setDefault("subcommand", this)
.setDefault("operation", this)
.help("List objects at path of location")
.description("List objects at path of location");
subparser.addArgument("location")
Expand Down
125 changes: 94 additions & 31 deletions src/main/java/nl/esciencecenter/xenon/cli/Main.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
package nl.esciencecenter.xenon.cli;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import nl.esciencecenter.xenon.AdaptorStatus;
import nl.esciencecenter.xenon.Xenon;
import nl.esciencecenter.xenon.XenonException;
import nl.esciencecenter.xenon.XenonFactory;
import nl.esciencecenter.xenon.XenonPropertyDescription;

import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.*;
import nl.esciencecenter.xenon.*;
import net.sourceforge.argparse4j.inf.ArgumentGroup;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class Main {
private static final String PROGRAM_NAME = "xenon";
private static final String PROGRAM_VERSION = "1.0.0";
Expand Down Expand Up @@ -39,36 +53,74 @@ public static Map<String,String> buildXenonProperties(Namespace res) {
}

public ArgumentParser buildArgumentParser() throws XenonException {
ArgumentParser parser = ArgumentParsers.newArgumentParser(PROGRAM_NAME)
ArgumentParser parser = ArgumentParsers.newArgumentParser(PROGRAM_NAME, true, "-", "@")
.defaultHelp(true)
.description("Files and Jobs operations with Xenon")
.version(PROGRAM_VERSION);
parser.addArgument("--version").action(Arguments.version());

parser.addArgument("--scheme").choices(getSchemeNames())
.setDefault(getDefaultSchemeName())
.help("Xenon scheme to use for subcommands");
parser.addArgument("--json").action(Arguments.storeTrue()).setConst(false).help("Output in JSON format");

ArgumentGroup propGroup = parser.addArgumentGroup("optional adaptor properties");
propGroup.addArgument("--prop")
.action(Arguments.append())
.metavar("KEY=VALUE")
.help("Xenon adaptor properties, " + getSupportedPropertiesHelp())
.dest("props");

parser.addArgument("--format").choices("cwljson").help("Output in JSON format");
addSchemeSubParsers(parser);
addCredentialArguments(parser);
return parser;
}

Subparsers subparsers = parser.addSubparsers().title("subcommands");
ICommand[] subcommands = {
new ListCommand(),
new UploadCommand(),
new DownloadCommand(),
};
for (ICommand subcommand: subcommands) {
subcommand.buildArgumentParser(subparsers);
private void addSchemeSubParsers(ArgumentParser parser) {
Subparsers subparsers = parser.addSubparsers().title("scheme");
AdaptorStatus[] adaptors = getAdaptorStatuses();

// TODO make filesSchemes+jobsSchemes dynamic after https://github.com/NLeSC/Xenon/issues/400 is fixed
List<String> filesSchemes = Arrays.asList("file", "sftp", "ftp");
List<String> jobsSchemes = Arrays.asList("local", "ssh", "ge", "sge", "slurm", "torque");
List<String> onlineSchemes = Arrays.asList("file", "local", "ssh", "sftp");
List<String> localSchemes = Arrays.asList("file", "local");

for (AdaptorStatus adaptor: adaptors) {
for (String scheme: adaptor.getSupportedSchemes()) {
Subparser schemeParser = subparsers.addParser(scheme)
.help(adaptor.getDescription())
.description(adaptor.getDescription())
.setDefault("scheme", scheme);
if (!localSchemes.contains(scheme)) {
// --location
}
schemeParser.addArgument("--prop")
.action(Arguments.append())
.metavar("KEY=VALUE")
.help("Xenon adaptor properties, " + getSupportedPropertiesHelp(adaptor))
.dest("props");
Subparsers commandsParser = schemeParser.addSubparsers().title("subcommands");
if (filesSchemes.contains(scheme)) {
if (!localSchemes.contains(scheme)) {
// upload
new UploadCommand().buildArgumentParser(commandsParser);
// download
new DownloadCommand().buildArgumentParser(commandsParser);
}
// copy
// remove
// list
new ListCommand().buildArgumentParser(commandsParser);
} else if (jobsSchemes.contains(scheme)) {
if (!onlineSchemes.contains(scheme)) {
// submit
// list
// remove
// queues
}
// exec
}
}
}
return parser;
}

private String getSupportedPropertiesHelp(AdaptorStatus adaptor) {
String sep = System.getProperty("line.separator");
List<String> helps = Arrays.stream(adaptor.getSupportedProperties()).map(
(property) -> "- " + property.getName() + "=" + property.getDefaultValue() + " ("+ property.getDescription() + ", type:" + property.getType() + ") "
).collect(Collectors.toList());

helps.add(0, "Supported properties:");
return String.join(sep, helps);
}

private void addCredentialArguments(ArgumentParser parser) {
Expand All @@ -84,13 +136,24 @@ private String getDefaultSchemeName() {

private List<String> getSchemeNames() throws XenonException {
ArrayList<String> schemeNames = new ArrayList<String>();
Xenon xenon = XenonFactory.newXenon(null);
AdaptorStatus[] adaptors = xenon.getAdaptorStatuses();
XenonFactory.endXenon(xenon);
AdaptorStatus[] adaptors = getAdaptorStatuses();
Arrays.stream(adaptors).forEach((adaptor) -> Collections.addAll(schemeNames, adaptor.getSupportedSchemes()));
return schemeNames;
}

private AdaptorStatus[] getAdaptorStatuses() {
AdaptorStatus[] adaptors = {};
try {
Xenon xenon = XenonFactory.newXenon(null);
adaptors = xenon.getAdaptorStatuses();
XenonFactory.endXenon(xenon);
return adaptors;
} catch (XenonException e) {
e.printStackTrace();
}
return adaptors;
}

private List<XenonPropertyDescription> getSupportedProperties() {
ArrayList<XenonPropertyDescription> props = new ArrayList<>();
try {
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/nl/esciencecenter/xenon/cli/UploadCommand.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package nl.esciencecenter.xenon.cli;

import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;
import nl.esciencecenter.xenon.Xenon;
import nl.esciencecenter.xenon.XenonException;
import nl.esciencecenter.xenon.credentials.Credential;
import nl.esciencecenter.xenon.files.Files;

import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import net.sourceforge.argparse4j.inf.Subparsers;

public class UploadCommand extends CopyCommand {

@Override
public Subparser buildArgumentParser(Subparsers subparsers) {
Subparser subparser = subparsers.addParser("upload")
.setDefault("subcommand", this)
.setDefault("operation", this)
.help("Upload local file to target")
.description("Upload local file to target");
subparser.addArgument("sourcePath").help("Source path").required(true);
Expand Down

0 comments on commit 6f58070

Please sign in to comment.