diff --git a/src/main/java/org/rundeck/client/api/RundeckApi.java b/src/main/java/org/rundeck/client/api/RundeckApi.java index 2ba24fea..862179c4 100644 --- a/src/main/java/org/rundeck/client/api/RundeckApi.java +++ b/src/main/java/org/rundeck/client/api/RundeckApi.java @@ -90,6 +90,13 @@ Call<DeleteJobsResult> deleteJobs( @GET("projects") Call<List<ProjectItem>> listProjects(); + /** + * @see <a href="http://rundeck.org/docs/api/#getting-project-info">API</a> + */ + @Headers("Accept: application/json") + @GET("project/{project}") + Call<ProjectItem> getProjectInfo(@Path("project") String project); + /** * * @see <a href="http://rundeck.org/docs/api/index.html#listing-resources">api</a> diff --git a/src/main/java/org/rundeck/client/api/model/ProjectItem.java b/src/main/java/org/rundeck/client/api/model/ProjectItem.java index 8cb33425..c350d389 100644 --- a/src/main/java/org/rundeck/client/api/model/ProjectItem.java +++ b/src/main/java/org/rundeck/client/api/model/ProjectItem.java @@ -51,12 +51,17 @@ public void setConfig(Map<String, String> config) { this.config = config; } - public Map<Object, Object> toMap() { + public Map<Object, Object> toBasicMap() { HashMap<Object, Object> detail = new LinkedHashMap<>(); detail.put("name", getName()); detail.put("description", description != null && !"".equals(description.trim()) ? description : ""); detail.put("url", getUrl()); + return detail; + } + public Map<Object, Object> toMap() { + + HashMap<Object, Object> detail = new LinkedHashMap<>(toBasicMap()); if (null != getConfig()) { detail.put("config", getConfig()); } diff --git a/src/main/java/org/rundeck/client/tool/commands/Projects.java b/src/main/java/org/rundeck/client/tool/commands/Projects.java index f19fe6e5..b23204cd 100644 --- a/src/main/java/org/rundeck/client/tool/commands/Projects.java +++ b/src/main/java/org/rundeck/client/tool/commands/Projects.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -49,31 +50,49 @@ interface ProjectResultOptions extends ProjectListFormatOptions, VerboseOption { } - @Command(isDefault = true, description = "List all projects. (no options.)") + @Command(isDefault = true, description = "List all projects.") public void list(ProjectListOpts opts, CommandOutput output) throws IOException, InputError { List<ProjectItem> body = apiCall(RundeckApi::listProjects); if (!opts.isOutputFormat()) { output.info(String.format("%d Projects:%n", body.size())); } - outputProjectList(opts, output, body); + outputProjectList(opts, output, body, ProjectItem::getName, ProjectItem::toMap); + } + + @CommandLineInterface(application = "info") interface ProjectInfoOpts extends ProjectResultOptions { + + @Option(shortName = "p", longName = "project", description = "Project name") + String getProject(); + + } + + @Command(isDefault = true, + description = "Get info about a project. Use -v/--verbose to output all available config data, or use " + + "-%/--outformat for selective data.") + public void info(ProjectInfoOpts opts, CommandOutput output) throws IOException, InputError { + ProjectItem body = apiCall(api -> api.getProjectInfo(opts.getProject())); + + outputProjectList(opts, output, Collections.singletonList(body), ProjectItem::toBasicMap, ProjectItem::toMap); } private void outputProjectList( final ProjectResultOptions options, final CommandOutput output, - final List<ProjectItem> body + final List<ProjectItem> body, + final Function<ProjectItem, Object> basicOutput, + final Function<ProjectItem, Map<Object, Object>> verboseOutput ) { final Function<ProjectItem, ?> outformat; if (options.isVerbose()) { - output.output(body.stream().map(ProjectItem::toMap).collect(Collectors.toList())); + output.output(body.stream().map(verboseOutput).collect(Collectors.toList())); return; } if (options.isOutputFormat()) { outformat = Format.formatter(options.getOutputFormat(), ProjectItem::toMap, "%", ""); } else { - outformat = ProjectItem::getName; + outformat = basicOutput; } output.output(body.stream().map(outformat).collect(Collectors.toList())); diff --git a/src/main/java/org/rundeck/client/tool/options/ProjectListFormatOptions.java b/src/main/java/org/rundeck/client/tool/options/ProjectListFormatOptions.java index 50031ced..52c795dd 100644 --- a/src/main/java/org/rundeck/client/tool/options/ProjectListFormatOptions.java +++ b/src/main/java/org/rundeck/client/tool/options/ProjectListFormatOptions.java @@ -10,7 +10,7 @@ public interface ProjectListFormatOptions { @Option(shortName = "%", longName = "outformat", - description = "Output format specifier for project info. You can use \"%key\" where key is one of:" + + description = "Output format specifier for project info. You can use \"%key\" where key is one of: " + "name, description, url, config, config.KEY. E.g. \"%name: " + "%description\".") String getOutputFormat();